vue写todo页面(9)

模板地址:vue官网上的示例
1 输入框输入,回车添加todo信息
2 每条todo信息后增加删除按钮
3 每条todo信息增加complete状态,列表前增加checkbox,选中后修改complete值,根据complete值修改todo信息样式
4 编辑:双击todo信息隐藏checkout、info、button,显示输入框,回车或失去焦点完成编辑,esc退出编辑
5 提示剩余未完成todo数量,清除已完成todo
6 增加显示筛选条件
7 全选
8 将数据保存在localStorage中
9 加样式
在这里插入图片描述

<html>

<head>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <style>
        .completed {
      
      
            text-decoration: line-through;
            color: lightgray;
        }

        #root {
      
      
            border: 1px solid darkgray;
        }

        header {
      
      
            border-bottom: 1px solid lightgray;
            height: 30px;
            padding: 5px;
        }

        input {
      
      
            margin: 0;
            padding: 0;
        }

        header>.allDone {
      
      
            display: inline-block;
            vertical-align: -webkit-baseline-middle;
            width: 15px;
        }

        header>.newTodo {
      
      
            outline: none;
            border: none;
            vertical-align: sub;
        }

        ul {
      
      
            padding: 0;
            margin: 0;
        }

        ul>li {
      
      
            list-style-type: none;
            padding: 5px;
            border-bottom: 1px solid lightgray;
        }

        button {
      
      
            border-color: transparent;
            background-color: transparent;
            color: darkgray;
            float: right;
        }

        footer {
      
      
            height: 24px;
            padding: 0 5px;
            color: darkgray;
            font-size: 12px;
            line-height: 24px;
            text-align: center;
            position: relative;
        }

        footer> :first-child {
      
      
            float: left;
        }

        footer .filter {
      
      
            position: absolute;
            left: 50%;
            transform: translate(-50%, 0);
        }

        footer .filter a {
      
      
            margin: 0 2px;
        }

        footer .checked {
      
      
            border: 1px solid lightgray;
        }
    </style>
</head>

<body>
    <div id="root">
        <header>
            <!-- 全选 -->
            <div class="allDone">
                <input v-show="todoList.length" type="checkbox" v-model="allDone" />
            </div>
            <!-- 输入框 -->
            <input class="newTodo" v-model="newTodo" @keyup.enter="addTodo" />
        </header>
        <!-- todo列表 -->
        <ul>
            <li v-for="(todo, index) in filterTodoList" :class="{completed: todo.completed}">
                <div v-show="editTodoIndex != index">
                    <!-- 状态勾选 -->
                    <input type="checkbox" v-model="todo.completed" />
                    <!-- todo信息 -->
                    <label @dblClick="editTodo(todo, index)">{
   
   {todo.info}}</label>
                    <!-- 删除按钮 -->
                    <button @click="removeTodo(index)">x</button>
                </div>
                <!-- 编辑框 -->
                <input style="marginLeft: 20px" v-show="editTodoIndex == index" v-model="todo.info"
                    @blur="doneEdit(todo, index)" @keyup.enter="doneEdit(todo, index)"
                    @keyup.esc="cancelEdit(todo, index)" />
            </li>
        </ul>
        <footer v-show="todoList.length">
            <!-- 未完成todo数 -->
            <a>剩下{
   
   {remainCount}}</a>
            <!-- 不同状态筛选 -->
            <div class="filter">
                <a :class="{checked: visible == 'all'}" @click="changeVisible('all')">所有</a>
                <a :class="{checked: visible == 'active'}" @click="changeVisible('active')">未完成</a>
                <a :class="{checked: visible == 'completed'}" @click="changeVisible('completed')">已完成</a>
            </div>
            <!-- 清除已完成todo -->
            <button v-show="todoList.length > remainCount" @click="clearComplete">清除已完成</button>
        </footer>
    </div>

    <script>
        var key = 'todoList';
        // 不同状态的筛选函数
        var filters = {
      
      
            all: function (todoList) {
      
      
                return todoList;
            },
            active: function (todoList) {
      
      
                return todoList.filter(todo => !todo.completed);
            },
            completed: function (todoList) {
      
      
                return todoList.filter(todo => todo.completed)
            }
        }
        // fetch从localstorage中获取数据,save将数据保存到localstorage中
        var todoStorage = {
      
      
            fetch: function () {
      
      
                return JSON.parse(localStorage.getItem(key) || "[]");
            },
            save: function (todoList) {
      
      
                localStorage.setItem(key, JSON.stringify(todoList));
            }
        }
        var app = new Vue({
      
      
            el: "#root",
            data: {
      
      
                newTodo: "", // 新增输入框的内容
                todoList: todoStorage.fetch(), // 所有todo信息,数组元素:{completed: 完成true/未完成false,info:todo信息string}
                editTodoIndex: -1, // 正在编辑的todo信息的index,没有todo信息正在编辑即为-1
                beforeEditCache: "", // 暂存编辑之前的todo信息,退出编辑后需要赋值回去
                visible: 'all' //当前筛选状态
            },
            methods: {
      
      
                // 回车添加事件
                addTodo: function () {
      
      
                    if (this.newTodo) {
      
      
                        this.todoList.push({
      
       info: this.newTodo, completed: false })
                    }
                    this.newTodo = '';
                },
                // 删除事件
                removeTodo: function (index) {
      
      
                    this.todoList.splice(index, 1)
                },
                // 开始编辑,保存编辑之前的todo信息,todo信息的index
                editTodo: function (todo, index) {
      
      
                    this.beforeEditCache = todo.info; // 不要保存整个todo,因为编辑的时候直接改变todo.info,beforeEditCache也会改变
                    this.editTodoIndex = index;
                },
                // 完成编辑,将editTodoIndex恢复初始值,如果输入框为空,则删除当前todo
                doneEdit: function (todo, index) {
      
      
                    this.editTodoIndex = -1;
                    if (!todo.info) {
      
      
                        this.removeTodo(index);
                    }
                },
                // 退出编辑
                cancelEdit: function (todo, index) {
      
      
                    todo.info = this.beforeEditCache;
                    this.editTodoIndex = -1;
                },
                // 清除已完成
                clearComplete: function () {
      
      
                    this.todoList = this.todoList.filter(todo => !todo.completed)
                },
                // 改变列表展示属性
                changeVisible: function (visible) {
      
      
                    this.visible = visible
                }
            },
            computed: {
      
      
                // 实时计算剩余未完成todo数
                remainCount: function () {
      
      
                    return this.todoList.filter(todo => !todo.completed).length;
                },
                // 根据筛选状态显示todo信息
                filterTodoList: function () {
      
      
                    return filters[this.visible](this.todoList)
                },
                // 全选,get获取值,判断是否全部完成,set赋值,将所有事件的completed全部置true
                allDone: {
      
      
                    get: function () {
      
      
                        return this.remainCount == 0;
                    },
                    set: function (value) {
      
      
                        this.todoList.forEach(todo => todo.completed = value);
                    }
                }
            },
            watch: {
      
      
                // 监听todoList,有改变的时候将新的数组保存到localstorage中
                todoList: {
      
      
                    handler: function () {
      
      
                        todoStorage.save(this.todoList);
                    },
                    deep: true,
                }
            }
        })

    </script>
</body>

</html>

猜你喜欢

转载自blog.csdn.net/weixin_43915401/article/details/123799214