vue入门练手:todo列表

原教程:https://juejin.im/post/5c3e9f946fb9a049f06a85ff#comment
按照dalao教的方法一步一步写的一个简单的vue实例,算是帮自己熟悉一下vue的基本指令和操作吧。
因为是个简单的例子,所有代码就直接写在了一个html文件里,也没加样式。
全部代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue Todo</title>
    <style>
        .completed {
            text-decoration: line-through;
        }

        .selected {
            color: red;
        }
        .hide{
            color: red;
            display: inline;

        }
        .empty{
            border-color: red;
        }
        p{
            display: none;
        }
        #todo-app{
            border: gray 2px solid;
            padding: 50px;
            position: absolute;
            top:50%;
            left:50%;
            transform: translate(-50%,-50%);
        }
    </style>
</head>
<body>
<div id="todo-app">
    <div>
        <input type="button"
               @click="allCompleted"
               v-if="leftTodosCount!==0"
               value="全部标为完成"/>
        <input type="text"
               v-bind:class='{empty:!ifempty}'
               v-model="newTodoTitle"
               @keyup.enter="addTodo"
               placeholder="添加 todo"/>
        <p v-bind:class='{hide:!ifempty}'>请输入内容</p>
    </div>
    <!-- todo list -->
    <ul>
        <li v-for='todo in filteredTodos' :key='todo.id'>
            <span
                    @dblclick="editeTodo(todo)"
                    :class="{completed: todo.completed}">{{ todo.title }}</span>
            <input
                    @click="markAsCompleted(todo)"
                    v-if="!todo.completed"
                    type="button" value="标为完成">
            <input
                    @click="markAsUncompleted(todo)"
                    v-if="todo.completed"
                    type="button" value="标为未完成">
            <input type="button"
                   @click="deleteTodo(todo)"
                   value="删除">
            <input type="text"
                   v-if="editedTodo!==null && editedTodo.id===todo.id"
                   v-model="todo.title"
                   @keyup.enter="editDone(todo)"
                   @keyup.esc="cancelEdit(todo)"
                   v-focus="true"
                   value="编辑 todo..."/>
            <span v-if="editedTodo!==null && editedTodo.id===todo.id" style="color: gray">回车键保存,esc键取消更改</span>
        </li>

    </ul>
    <!-- end todo list -->
    <div>
        <span>剩余 {{leftTodosCount}} 项未完成 ---</span>
        <span>筛选:
      <input type="button"
             @click="intention='all'"
             :class="{selected:intention==='all'}"
             value="全部">
      <input type="button"
             @click="intention='ongoing'"
             :class="{selected:intention==='ongoing'}"
             value="进行中">
      <input type="button"
             @click="intention='finished'"
             :class="{selected:intention==='finished'}"
             value="已完成">
      <input type="button"
             @click="deleteCompletedTodos"
             v-if="finishedTodosCount!==0"
             value="清除已完成">
      <input type="button"
             @click="deleteAllTodos"
             value="清除全部">
      <input type="button"
             @click="undo"
             v-if="deletedTodos.length!==0"
             value="撤销删除">
    </span>
    </div>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script>
<script>
    var STORAGE_KEY = 'vue2.x-todo';
    //本地储存组件
    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))

        }
    };
    let id=0;
    var app = new Vue({
        el: '#todo-app',
        data: function () {
            return {
                todos: todoStorage.fetch(),
                deletedTodos: [],
                newTodoTitle:'',
                checkEmpty:false,//是否检测输入栏为空
                editedTodo:null,//暂存编辑前的todo
                intention:'all',//当前查看的状态,默认为全显示


            }
        },
        //======================================================================================================
//侦听属性
        watch:{
            todos:{
                handler: function (todos) {
                    todoStorage.save(todos)

                },
                deep:true
            }

        },
//======================================================================================================
//基本方法
        methods: {
            addTodo: function () {
                if (!this.newTodoTitle == '') {
                    this.todos.push({id: todoStorage.uid++, title: this.newTodoTitle, completed: false});
                    this.newTodoTitle = '';
                    this.checkEmpty = false;
                }
                else {
                    this.checkEmpty = true;
                }
            },
            deleteTodo: function (todo) {
                if (todo.title === '') {
                    this.deletedTodos.push({todo: this.editedTodo, pos: todo.id});
                }
                else {
                    this.deletedTodos.push({todo: todo, pos: todo.id});
                }
                this.todos.splice(this.todos.indexOf(todo), 1);
            },
            editeTodo: function (todo) {
                this.editedTodo = {id: todo.id, title: todo.title, completed: todo.completed}

            },
            markAsCompleted: function (todo) {
                todo.completed = true;

            },
            markAsUncompleted: function (todo) {
                todo.completed = false;
            },
            undo: function () {
                if (!this.deletedTodos.length == 0) {
                    let a = this.deletedTodos.pop();
                    this.todos.splice(a.pos, 0, a.todo)
                }
            },
            editDone: function (todo) {
                if (todo.title === '') {
                    this.deleteTodo(todo);
                }
                this.editedTodo = null;

            },
            cancelEdit: function (todo) {
                todo.title = this.editedTodo.title;
                this.editedTodo == null;

            },
            allCompleted:function () {
               this.todos.map(
                       todo => todo.completed = true

               )
            },
            deleteAllTodos:function () {
                if(confirm("此操作不可恢复,确定要全部清除吗?")){
                    this.todos=[];
                }


            },
            deleteCompletedTodos:function () {
                if(confirm("此操作不可恢复,确定要清除全部完成项目吗?")){
                    this.todos=this.todos.filter(todo=>!todo.completed)
                }


            }

        },
//===========================================================================================
//钩子函数,自动聚焦编辑栏
        directives:{
            focus:{
                inserted:function (el) {
                    el.focus()

                }
            }

        },
//======================================================================================================
//计算属性
        computed:{
            ifempty:function () {
                if(this.checkEmpty) {
                    return this.newTodoTitle.length;
                }

                return 1;
            },
            leftTodos:function(){
              return this.todos.filter(todo=> !todo.completed)
            },
            leftTodosCount:function () {
                return this.leftTodos.length

            },
            finishedTodos:function(){
                return this.todos.filter(todo=>todo.completed)
            },
            finishedTodosCount:function(){
                return this.finishedTodos.length
            },
            filteredTodos:function () {
                if(this.intention==='ongoing'){
                    return this.leftTodos
                }
                else if(this.intention==='finished'){
                    return this.finishedTodos
                }else{
                    return this.todos
                }

            }
        }

    })
</script>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值