参考教程 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>
最后修改:2021 年 05 月 14 日
如果觉得我的文章对你有用,请随意赞赏