之前做好的todoList程序几乎没有使用什么css,都是原生的html样式,看起来有点low,接下来使用element ui来给他装个皮肤

(在线体验)

效果图

image.png

image.png

image.png

image.png

image.png

修改后的代码

<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <title>Vue Todo</title>
        <style>
            body {
                margin: 0;
                padding: 0;
            }

            .completed {
                text-decoration: line-through;
                color: gray
            }

            .selected {
                color: lightseagreen;
            }

            .empty {
                border-color: red;
            }

            .editTodo {
                font-size: 18px;
                width: 80%;
            }
        </style>
        <!-- 引入样式 -->
        <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
        <!-- import Vue before Element -->
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
        <!-- import JavaScript -->
        <script src="https://unpkg.com/element-ui/lib/index.js"></script>
    </head>

    <body>
        <div id="todo-app">
            <el-row :gutter="20">
                <el-col :span="16" :offset="4">
                    <div class="grid-content bg-purple">
                        <el-container style="min-width: 500px;margin: 0 auto;">
                            <el-header>
                                <div style="margin-top: 20px;">
                                    <!-- <input type="button" v-if="onGoingTodosCount" @click="markAllAsCompleted" value="全部标为完成" /> -->
                                    <!-- <input type="text" :class="{empty:emptyChecked}" placeholder="添加 todo" / v-model="newTodoTitle"
                                        @keyup.enter="addTodo"> -->
                                    <el-input placeholder="添加 todo" v-model="newTodoTitle" @keyup.enter.native="addTodo"
                                        minlength=1 clearable>
                                    </el-input>
                                    <span v-if="emptyChecked" style="color: #FF0000;">请输入内容!</span>
                                </div>
                            </el-header>
                            <el-main>
                                <!-- todo list -->
                                <el-card class="box-card">
                                    <div slot="header" class="clearfix">
                                        <span>代办清单:</span>
                                        <el-button style="float: right; padding: 3px 0" type="text" size="mini"
                                            v-if="onGoingTodosCount" @click="markAllAsCompleted">全部标为完成</el-button>
                                    </div>
                                    <div v-for='todo in filteredTodo' :key='todo.id' class="text item">
                                        <el-card shadow="hover">
                                            <el-tooltip v-if="editedTodo && editedTodo.id === todo.id" class="item"
                                                effect="dark" content="按Enter确认,点击其他区域或按Esc取消编辑" placement="top">
                                                <input type="text" value="编辑 todo..." class="editTodo"
                                                    v-model="todo.title" v-focus=1 @keyup.enter="editDone(todo)"
                                                    @keyup.esc="editCancle(todo)" @blur="editCancle(todo)" />
                                            </el-tooltip>

                                            <span :class="{completed: todo.completed}" v-else @dblclick="editTodo(todo)"
                                                style="font-size: 20px;max-width: 80%;display: inline-block;">{{ 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)">
                                                 -->
                                            <div class='controlButtons' style="float: right;">
                                                <el-tooltip class="item" effect="dark" content="编辑" placement="top">
                                                    <el-button type="primary" size="mini" icon="el-icon-edit" circle
                                                        @click="editTodo(todo)"></el-button>
                                                </el-tooltip>
                                                <el-tooltip v-if="!todo.completed" class="item" effect="dark"
                                                    content="标记完成" placement="top">
                                                    <el-button size="mini" type="success" icon="el-icon-check" circle
                                                        @click="markAsCompleted (todo)" style="margin: 0 5px;">
                                                    </el-button>
                                                </el-tooltip>
                                                <el-tooltip v-else class="item" effect="dark" content="标记未完成"
                                                    placement="top">
                                                    <el-button size="mini" @click="markAsCompleted (todo)" type="info"
                                                        icon="el-icon-close" circle style="margin: 0 5px;"></el-button>
                                                </el-tooltip>
                                                <el-tooltip class="item" effect="dark" content="删除" placement="top">
                                                    <el-popconfirm title="确定删除吗?" @Confirm="removeTodo(todo)">
                                                        <el-button size="mini" type="danger" circle
                                                            icon="el-icon-delete" slot="reference"></el-button>
                                                    </el-popconfirm>
                                                </el-tooltip>
                                            </div>
                                        </el-card>
                                    </div>
                                </el-card>
                                <!-- end todo list -->
                            </el-main>

                            <el-footer>
                                <div>
                                    <span v-if="onGoingTodosCount">剩余 {{onGoingTodosCount}} 项未完成 ---</span>
                                    <span v-else>无未完成代办事项</span>
                                    <span>筛选:
                                        <!-- <input type="button" :class="{selected:intention=='all'}" value="全部" @click="intention='all'"> -->
                                        <el-button size="mini" :type="buttonType(intention)[0]"
                                            @click="intention='all'">全部
                                        </el-button>
                                        <!-- <input type="button" :class="{selected:intention=='ongoing'}" value="进行中"
                                            @click="intention='ongoing'"> -->
                                        <el-button size="mini" :type="buttonType(intention)[1]"
                                            @click="intention='ongoing'">进行中
                                        </el-button>
                                        <!-- <input type="button" :class="{selected:intention=='finished'}" value="已完成"
                                            @click="intention='finished'"> -->
                                        <el-button size="mini" :type="buttonType(intention)[2]"
                                            @click="intention='finished'">已完成
                                        </el-button>
                                        <!-- <input type="button" v-if="onGoingTodosCount" value="清除已完成" @click="clearCompleted">
                                        <input type="button" v-if="hasTodo" value="清除全部" @click="clearAll"> -->
                                        <el-button size="mini" v-if="onGoingTodosCount" @click="clearCompleted">清除已完成
                                        </el-button>
                                        <el-button size="mini" v-if="hasTodo" @click="clearAll">清除全部</el-button>
                                    </span>
                                </div>
                                <!-- <div>
                                    <el-button @click="visible = true">Button</el-button>
                                    <el-dialog :visible.sync="visible" title="Hello world">
                                        <p>Try Element</p>
                                    </el-dialog>
                                </div> -->
                            </el-footer>
                        </el-container>
                    </div>
                </el-col>
            </el-row>

        </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',
                        visible: false,
                        buttonType: function(val) {
                            if (val == 'finished') {
                                return ['', '', 'primary']
                            } else if (val == 'ongoing') {
                                return ['', 'primary', '']
                            } else {
                                return ['primary', '', '']
                            }

                        }
                    }
                },
                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)
                        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() {
                        // if (!confirm('确认删除?')) {
                        //     return
                        // }
                        this.$confirm('确认要删除代所有待办事项吗?', '提示', {
                            confirmButtonText: '确定',
                            cancelButtonText: '取消',
                            type: 'warning'
                        }).then(() => {
                            this.$message({
                                type: 'success',
                                message: '删除成功!'
                            });
                            this.todoList = []
                        }).catch(() => {
                            this.$message({
                                type: 'info',
                                message: '已取消删除'
                            });
                        });

                    },
                    clearCompleted() {
                        this.$confirm('确认要删除代已完成的事项吗?', '提示', {
                            confirmButtonText: '确定',
                            cancelButtonText: '取消',
                            type: 'warning'
                        }).then(() => {
                            this.$message({
                                type: 'success',
                                message: '删除成功!'
                            });
                            this.todoList = this.todoList.filter(todo => !todo.completed)
                        }).catch(() => {
                            this.$message({
                                type: 'info',
                                message: '已取消删除'
                            });
                        });

                    }
                },
                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>

注意点

注释掉的基本上是之前的代码,可以做一个对比。

删除单条数据的时候,本来写了一个弹框确定删除的函数,但是发现有更方便的办法,可以直接用<el-popconfirm></el-popconfirm>这个标签来实现。有一个要注意的地方就是用了这个以后,button上原本绑定的click事件好像就失效了,可以改成在这个标签内使用@Confirm="removeTodo(todo)"来代替。也有说要用@onConfirm的,我试了好像不行。

还有就是input标签里面绑定的@keyup.enter事件要改成@keyup.enter.native才行

疑问

最下面那一排筛选的按钮,本来是点击之后会增加一个.selected的样式,代码是:class="{selected:intention=='all'} @click="intention='all'",用el-button之后想要动态的改变type样式,好像无法使用这种方式,最后只好用了一个数组来存放每个按钮的状态,感觉有点low,不知道有没有更好的办法。

存储的部分直接抄了教程的代码,没有搞的太明白,之后再研究研究。

最后修改:2021 年 05 月 15 日
如果觉得我的文章对你有用,请随意赞赏