参考教程 Vue 2.x Todo 教程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue Todo</title>
<style>
.completed {
text-decoration: line-through;
color:gray
}
.selected {
color: lightseagreen;
}
.empty {
border-color: red;
}
</style>
</head>
<body>
<div id="todo-app">
<div>
<input type="button" v-if="onGoingTodosCount" @click="markAllAsCompleted" value="全部标为完成" />
<input type="text" :class="{empty:emptyChecked}" placeholder="添加 todo" / v-model="newTodoTitle"
@keyup.enter="addTodo">
<span v-if="emptyChecked" style="color: #FF0000;">请输入内容!</span>
</div>
<!-- todo list -->
<ul>
<li v-for='todo in filteredTodo' :key='todo.id'>
<span :class="{completed: todo.completed}" @dblclick="editTodo(todo)">{{ todo.title }}</span>
<input type="button" value="标记已完成" v-if="!todo.completed" @click="markAsCompleted (todo)" />
<input type="button" value="标记未完成" v-else @click="markAsCompleted (todo)" />
<input type="button" value="删除" @click="removeTodo(todo)">
<input v-if="editedTodo && editedTodo.id === todo.id" type="text" value="编辑 todo..."
v-model="todo.title" v-focus=1 @keyup.enter="editDone(todo)" @keyup.esc="editCancle(todo)" />
</li>
</ul>
<!-- end todo list -->
<div v-if="hasRemovedTodo">
<input type="button" value="撤销" @click="restoreTodo()" />
</div>
<div>
<span v-if="onGoingTodosCount">剩余 {{onGoingTodosCount}} 项未完成 ---</span>
<span v-else>无未完成代办事项</span>
<span>筛选:
<input type="button" :class="{selected:intention=='all'}" value="全部" @click="intention='all'">
<input type="button" :class="{selected:intention=='ongoing'}" value="进行中" @click="intention='ongoing'">
<input type="button" :class="{selected:intention=='finished'}" value="已完成" @click="intention='finished'">
<input type="button" v-if="onGoingTodosCount" value="清除已完成" @click="clearCompleted">
<input type="button" v-if="hasTodo" value="清除全部" @click="clearAll">
</span>
</div>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script>
<script type="text/javascript">
let id = 0;
var STORAGE_KEY = 'vue2.x-todo-tutorial';
var todoStorage = {
fetch: function () {
var todos = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]');
todos.forEach(function (todo, index) {
todo.id = index
});
todoStorage.uid = todos.length;
return todos
},
save: function (todos) {
localStorage.setItem(STORAGE_KEY, JSON.stringify(todos))
}
};
var app = new Vue({
el: '#todo-app',
data: function() {
return {
todoList: todoStorage.fetch(),
newTodoTitle: '',
checkEmpty: false,
removedTodo: [],
editedTodo: null, // 用于暂存编辑前的 todo 状态
intention:'all'
}
},
methods: {
addTodo() {
if (this.newTodoTitle.length) {
this.todoList.push({
id: todoStorage.uid++,
title: this.newTodoTitle,
completed: false,
markButtonText: "标为完成",
});
this.newTodoTitle = ''
this.checkEmpty = false;
} else {
this.checkEmpty = true
}
},
markAsCompleted(todo) {
todo.completed = !todo.completed;
},
removeTodo(todo) {
let pos = this.todoList.indexOf(todo)
if (!confirm('确认删除?')) {
return
}
this.removedTodo.push({
pos: pos,
title: this.todoList.splice(pos, 1)[0]
})
},
restoreTodo() {
let todo = this.removedTodo.pop()
this.todoList.splice(todo.pos, 0, todo.title)
},
editTodo(todo) {
this.editedTodo = {
id: todo.id,
title: todo.title,
completed: todo.completed,
markButtonText: todo.markButtonText
}
},
editDone(todo) {
if (!todo.title) {
todo.title = this.editedTodo.title
this.removeTodo(todo)
}
this.editedTodo = null
},
editCancle(todo) {
todo.title = this.editedTodo.title
this.editedTodo = null
},
markAllAsCompleted(){
this.todoList.map(function(todo){
todo.completed=true
})
},
clearAll(){
this.todoList = []
},
clearCompleted(){
this.todoList = this.todoList.filter(todo => !todo.completed)
}
},
computed: {
emptyChecked() {
return !this.newTodoTitle.length && this.checkEmpty
},
hasRemovedTodo() {
return this.removedTodo.length
},
onGoingTodos() {
return this.todoList.filter(todo => !todo.completed)
},
onGoingTodosCount() {
return this.todoList.filter(todo => !todo.completed).length
},
filteredTodo(){
if (this.intention==='ongoing'){
return this.onGoingTodos
}else if (this.intention==='finished') {
return this.todoList.filter(todo => todo.completed)
}else {
return this.todoList
}
},
hasTodo(){
return this.todoList.length
}
},
directives: {
focus: {
inserted: function(el) {
el.focus()
}
},
},
watch: {
todoList: {
handler: function (todoList) {
todoStorage.save(todoList)
},
deep: true
}
},
})
</script>
</body>
</html>