Vue.jsの理解の一助として簡易Todoリストアプリを作成してみました。
他のフレームワーク触っていないのでVue.jsの特性と言えるか分からないですが、作ってみてとても便利だと感じたのがリアクティブシステムです。
リアクティブシステムとは、
データ同士が紐付けられて、どちらか一方のデータが更新されると、もう一方も更新される仕組みのことです。
このリアクティブシステムをJavaScriptで実装しようとすると、処理が複雑になりコード量も多くなってしまいますが、リアクティブシステムを使うと処理が簡潔になるだけでなく、誰が書いても似たようなコードになるので、メンテナンスしやすいというメリットがあります。
データを同期させるためには、HTML要素に特別な属性を与えることが必要です。その属性のことを ディレクティブといい、Vue.jsが提供する属性であることを示す「v-」で始まる名前が付けられています。
v-bindは、JavaScriptのデータが更新されるとDOMのデータが更新される、一方通行でバインドするデータとして定義するディレクティブです。
v-modelは、双方向でバインドするデータとして定義するディレクティブで、v-bindの動作に加え、フォームからユーザーの入力があるたびにJavaScriptのデータを更新します。
上記らを用いることで、「チェックボックスを押下したら、タスク内容がグレーアウトする処理」を追加できます。
html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Vue.js TODO APP</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div id="to-do">
<p>
NewTask:
<input type="text" v-model="newTask">
<button @click="addTodo()">Add</button>
</p>
<hr>
<ul>
<li v-for="todo in todos">
<input type="checkbox" v-model="todo.isCompleted">
<span :class="{ 'complete': todo.isCompleted }">{{ todo.task }}</span>
<button @click="deleteTodo(todo)">Delete</button>
</li>
</ul>
</div>
<!-- Vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script src="./main.js"></script>
</body>
</html>
css
ul {
margin: 0;
padding: 0;
list-style-type: none;
}
ul > li {
margin: 5px;
text-indent: 0;
}
#to-do {
width: 800px;
margin: 0 auto;
}
ul > li > .complete {
text-decoration: line-through;
color: #ddd;
}
js
new Vue({
el: '#to-do',
data: {
newTask: '',
todos: [
{ task: 'Rubyの勉強をする', isCompleted: false },
{ task: 'Vue.jsのアプリを作る', isCompleted: false },
{ task: 'Youtubeをみる', isCompleted: false }
]
},
methods: {
addTodo: function() {
if (this.newTask == '') return;
this.todos.push(
{ task: this.newTask, isCompleted: false }
);
this.newTask = '';
},
deleteTodo: function (todo) {
var index = this.todos.indexOf(todo)
this.todos.splice(index, 1)
}
}
});