CDN での実装
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Todoリスト</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
</head>
<body>
<style type="text/css">
table {
width: 300px;
border-collapse: collapse;
border-spacing: 0;
}
table th,
table td {
padding: 10px 0;
text-align: center;
}
.finished {
text-decoration: line-through;
}
button:disabled {
background-color: #ccc;
}
</style>
<div id="app">
<input type="text" v-model="name" placeholder="hogehoge" />
<button @click="addTodo" :disabled="!name.length">ADD</button>
<p>残タスク数:{{ unfinishedTodoCount }}</p>
<p>終了率:{{ finishedRate }}%</p>
<table>
<thead>
<tr>
<th>
タイトル
</th>
<th>
完了済み
</th>
</tr>
</thead>
<tbody>
<tr v-for="(todo, i) in todos" :key="i">
<td :class="todo.done ? 'finished' : ''">
{{ todo.name }}
</td>
<td>
<input type="checkbox" v-model="todo.done" />
</td>
<td>
<button @click="deleteTodo(i)">
削除
</button>
</td>
</tr>
</tbody>
</table>
</div>
<script>
new Vue({
el: "#app",
data: {
name: "",
todos: [{ name: "hoge", done: false }]
},
beforeCreate() {
console.log("beforeCreate!");
},
created() {
console.log("created!");
},
beforeMount() {
console.log("beforeMount!");
},
mounted() {
console.log("mounted!");
},
methods: {
// やることを追加するメソッド
addTodo() {
this.todos.push({ name: this.name, done: false });
this.name = "";
},
// やることを削除するメソッド
deleteTodo(i) {
this.todos.splice(i, 1);
}
},
computed: {
// 終了していないタスクの数を返す
unfinishedTodoCount() {
return this.todos.filter(todo => !todo.done).length;
},
// 終了しているタスクの割合を返す
finishedRate() {
if (!this.todos.length) return 0;
const finishedTodoCount = this.todos.filter(todo => todo.done)
.length;
return (finishedTodoCount / this.todos.length) * 100;
}
},
watch: {
// nameを監視
name(newVal, oldVal) {
console.log(`newVal: ${newVal}`);
console.log(`oldVal: ${oldVal}`);
}
},
beforeUpdate() {
console.log("beforeUpdate!");
},
updated() {
console.log("updated!");
},
beforeDestroy() {
console.log("beforeDestroy!");
},
destroyed() {
console.log("destroyed!");
}
});
</script>
</body>
</html>
単一ファイルコンポーネントでの実装
App.vue
<template>
<div id="app">
<input type="text" v-model="name" placeholder="hogehoge" />
<button @click="addTodo" :disabled="!name.length">ADD</button>
<p>残タスク数:{{ unfinishedTodoCount }}</p>
<p>終了率:{{ finishedRate }}%</p>
<table>
<thead>
<tr>
<th>
タイトル
</th>
<th>
完了済み
</th>
</tr>
</thead>
<tbody>
<tr v-for="(todo, i) in todos" :key="i">
<td :class="todo.done ? 'finished' : ''">
{{ todo.name }}
</td>
<td>
<input type="checkbox" v-model="todo.done" />
</td>
<td>
<button @click="deleteTodo(i)">
削除
</button>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
data: () => ({
name: "",
todos: [{ name: "hoge", done: false }]
}),
beforeCreate() {
console.log("beforeCreate!");
},
created() {
console.log("created!");
},
beforeMount() {
console.log("beforeMount!");
},
mounted() {
console.log("mounted!");
},
methods: {
// やることを追加するメソッド
addTodo() {
this.todos.push({ name: this.name, done: false });
this.name = "";
},
// やることを削除するメソッド
deleteTodo(i) {
this.todos.splice(i, 1);
}
},
computed: {
// 終了していないタスクの数を返す
unfinishedTodoCount() {
return this.todos.filter(todo => !todo.done).length;
},
// 終了しているタスクの割合を返す
finishedRate() {
if (!this.todos.length) return 0;
const finishedTodoCount = this.todos.filter(todo => todo.done).length;
return (finishedTodoCount / this.todos.length) * 100;
}
},
watch: {
// nameを監視
name(newVal, oldVal) {
console.log(`newVal: ${newVal}`);
console.log(`oldVal: ${oldVal}`);
}
},
beforeUpdate() {
console.log("beforeUpdate!");
},
updated() {
console.log("updated!");
},
beforeDestroy() {
console.log("beforeDestroy!");
},
destroyed() {
console.log("destroyed!");
}
};
</script>
<style>
table {
width: 300px;
border-collapse: collapse;
border-spacing: 0;
}
table th,
table td {
padding: 10px 0;
text-align: center;
}
.finished {
text-decoration: line-through;
}
button:disabled {
background-color: #ccc;
}
</style>
LocalStorage を活用したデータの永続化
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Todoリスト</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
</head>
<body>
<style type="text/css">
table {
width: 300px;
border-collapse: collapse;
border-spacing: 0;
}
table th,
table td {
padding: 10px 0;
text-align: center;
}
.finished {
text-decoration: line-through;
}
button:disabled {
background-color: #ccc;
}
</style>
<div id="app">
<input type="text" v-model="name" placeholder="hogehoge" />
<button @click="addTodo" :disabled="!name.length">ADD</button>
<p>残タスク数:{{ unfinishedTodoCount }}</p>
<p>終了率:{{ finishedRate }}%</p>
<table>
<thead>
<tr>
<th>タイトル</th>
<th>完了済み</th>
</tr>
</thead>
<tbody>
<tr v-for="(todo, i) in todos" :key="i">
<td :class="todo.done ? 'finished' : ''">{{ todo.name }}</td>
<td>
<input type="checkbox" v-model="todo.done" />
</td>
<td>
<button @click="deleteTodo(i)">削除</button>
</td>
</tr>
</tbody>
</table>
</div>
<script>
new Vue({
el: "#app",
data: {
name: "",
todos: JSON.parse(window.localStorage.getItem("todos")) || []
},
beforeCreate() {
console.log("beforeCreate!");
},
created() {
console.log("created!");
},
beforeMount() {
console.log("beforeMount!");
},
mounted() {
console.log("mounted!");
},
methods: {
// やることを追加するメソッド
addTodo() {
this.todos.push({ name: this.name, done: false });
window.localStorage.setItem("todos", JSON.stringify(this.todos));
this.name = "";
},
// やることを削除するメソッド
deleteTodo(i) {
this.todos.splice(i, 1);
window.localStorage.setItem("todos", JSON.stringify(this.todos));
}
},
computed: {
// 終了していないタスクの数を返す
unfinishedTodoCount() {
return this.todos.filter(todo => !todo.done).length;
},
// 終了しているタスクの割合を返す
finishedRate() {
if (!this.todos.length) return 0;
const finishedTodoCount = this.todos.filter(
todo => todo.done
).length;
return (finishedTodoCount / this.todos.length) * 100;
}
},
watch: {
// nameを監視
name(newVal, oldVal) {
console.log(`newVal: ${newVal}`);
console.log(`oldVal: ${oldVal}`);
}
},
beforeUpdate() {
console.log("beforeUpdate!");
},
updated() {
console.log("updated!");
},
beforeDestroy() {
console.log("beforeDestroy!");
},
destroyed() {
console.log("destroyed!");
}
});
</script>
</body>
</html>