Vue.js ToDoリストアプリ作成のサンプルソースコード
■Vue.jsでToDoリストアプリのサンプルソースコード
Vue.jsの基本は下記
・Vue.js 基礎編①(基礎・v-if・v-show)
・Vue.js 基礎編②(v-for・v-on・methods)
・Vue.js 基礎編③(v-bind・computed)
・Vue.js 基礎編④(watch・mounted)
【index.html】
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
<title>ToDoリスト</title>
</head>
<body>
<div class="container">
<div id="result">
<h1>ToDoリスト</h1>
<hr>
<div class="sub_header">
<div class="list_count">
ToDoリスト数:{{ listCount.length }} / {{ lists.length }}
</div>
<div class="all_del">
<!-- 一括削除ボタン -->
<!-- @clickで一括削除ボタン押下時のイベントを設定 -->
<button type="button" @click="allDel">一括削除</button>
</div>
</div>
<div class="main">
<!-- @submit.preventで追加ボタン押下時のイベントを設定 -->
<!-- 「prevent」で他ページへの遷移を防止 -->
<form @submit.prevent="addList">
<div>
<!-- 入力した値を「v-model="newList"」でVue.jsのdataで設定した値と紐づけ -->
<input type="text" v-model="newList">
<input type="submit" value="追加">
</div>
</form>
<div>
<ul>
<!-- v-for="list in lists"でループ -->
<!-- 「index」でループの番号を取得 -->
<li v-for="(list, index) in lists">
<!-- チェックボックスのチェック有無を「v-model="list.isChecked"」でVue.jsのdataで設定した値と紐づけ -->
<input type="checkbox" name="checkbox" v-model="list.isChecked">
<!-- 「:class」は「v-bind:class」と同じ -->
<!-- 「:class="{checked: list.isChecked}"」でdataの「list.isChecked」がtrueだったら「checked」クラス要素を付与 -->
<span :class="{checked: list.isChecked}">{{ list.title }}</span>
<span class="del_mark" @click="delList(index)">[x]</span>
</li>
</ul>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="main.js"></script>
</body>
</html>
【main.js】
(() => {
'use strict';
let vm = new Vue({
el: '#result',
data: {
// 「newList」はテキストボックスに入力した値を受ける
newList: '',
lists: []
},
// ブラウザのLocalStorageにJSON形式で保存
watch: {
lists: {
handler: function(){
// dataの「lists」は「this.lists」で取得
localStorage.setItem('lists', JSON.stringify(this.lists));
},
deep: true
}
},
// ブラウザのLocalStorageから出力
mounted: function(){
this.lists = JSON.parse(localStorage.getItem('lists')) || [];
},
// 各イベント時の動作
methods: {
addList: function(){
let item = {
title: this.newList,
}
this.lists.push(item);
this.newList = '';
},
delList: function(index){
if (confirm('削除しますか?')) {
this.lists.splice(index, 1);
}
},
allDel: function(){
if (confirm('一括削除しますか?')) {
this.lists = this.listCount;
}
}
},
// 動的に算出
computed: {
listCount: function(){
return this.lists.filter(function(list){
return !list.isChecked;
});
}
}
});
})();
【style.css】
ul {
list-style: none;
}
.container {
font-size: 18px;
font-family: Verdana,sans-serif;
width: 500px;
margin: auto;
}
.sub_header {
padding: 20px 10px 50px;
}
.list_count {
float: left;
}
.all_del {
float: right;
}
.all_select {
float: right;
padding-right: 10px;
}
.main {
clear: both;
}
.del_mark {
font-size: 14px;
color: rgb(0,0,200);
cursor: pointer;
}
.checked {
color: rgb(200,200,200);
text-decoration: line-through;
}