Vue Todo—list案例2.0(Day28)

52 阅读3分钟

交互

复选框勾选已完成事件

方案1:

  1. 给复选框绑定点击事件
  2. 通过实参将该勾选框所在事件id传入后台
  3. 对该事件进行相应操作
//Item组件
<input type="checkbox" :checked="todo.done" @click="handleCheck(todo.id)">
    methods:{
        handleCheck(done){
            console.log(done)
        }
    }

方案2:

  1. 给复选框绑定change事件
  2. 通过实参将该勾选框所在事件id传入后台
  3. 对该事件进行相应操作
//Item组件
<input type="checkbox" :checked="todo.done" @change="handleCheck(todo.id)">
    methods:{
        handleCheck(done){
            console.log(done)
        }
    }

方案3:(用于布尔类型数值)

  1. 使用v-model方式将事件是否被选中在页面渲染
  2. 利用v-model双向数据绑定的特殊性
  3. 页面发生变化时,v-model同时改变后台数据的布尔值
  4. 注: 不建议使用此方法,此处对props中的值进行修改,原则上不修改props中的值
/* App、Item、List组件中不用配置和传递任何方法、数据
只在Item组件中重写input绑定事件 */
<input type="checkbox" v-model="todo.done">

任务项删除

  1. 为删除按钮绑定点击事件
  2. 点击按钮获取当前项的id并将其传给App组件
  3. 在App组件中定义删除事件
  4. 调用Array方法中的reduce方法将传入的id的事件筛选出事件数组列表
  5. 将结果返回给页面进行重新渲染
// App组件
 <List :todoArr="todoArr" :checkTodo="checkTodo" :deleteTodo="deleteTodo"></List>
        deleteTodo(id) {
            this.todoArr = this.todoArr.filter(todo => todo.id !== id)
        },
// List组件
            <Item v-for="item in todoArr"
                  :key="item.id"
                  :todo="item"
                  :checkTodo="checkTodo"
                  :deleteTodo="deleteTodo">
            </Item
            props: ['todoArr', 'checkTodo', 'deleteTodo']
// Item组件
<button class="btn btn-danger" @click="deleteItem(todo.id)">删除</button>
		// 删除任务项
        deleteItem(id){
            if (confirm('确定要删除此任务吗?')){
                this.deleteTodo(id)
            }
        }

底部任务项统计

全部

  1. 利用computed方法计算出任务列表长度
  2. 将计算结果利用模版语法渲染至页面
        total() {
            return this.todoArr.length
        },

已完成

  1. 利用数组reduce方法将已完成任务项数量进行统计
  2. 利用computed方法将结果计算出来
  3. 将结果利用模版语法渲染至页面
<span>已完成 {{ doneTotal }}</span> /全部 {{ total }}
        doneTotal() {
            return this.todoArr.reduce((pre, current) => pre + (current.done ? 1 : 0), 0)
        },

全选或全不选

全部完成后自动勾选
  1. 当上述已完成的计算结果与全部计算结果相等时,全选框勾选
  2. 当任务列表为零时,底部隐藏
    <div class="myfooter" v-show="total">
        <label>
           <input type="checkbox" :checked="isAll">
        </label>
        <span>已完成 {{ doneTotal }}</span> /全部 {{ total }}
        <button class="btn btn-danger">清除已完成任务</button>
    </div>
            isAll() {
            return this.total === this.doneTotal && this.total > 0
        }
自主勾选全选或全不选

方案1:利用change事件

  1. 绑定change事件监听该元素并将其是否选中的布尔值传入
  2. 在App组件中定义全选或全不选事件
  3. 获取传入参数,并将该值全部赋值给列表项中的done属性
  4. 将该事件传入MyFooter组件
  5. 在change事件中调用该方法
//App组件
 <MyFooter :todoArr="todoArr" :checkAllTodos="checkAllTodos"></MyFooter>
         // 全选或取消全选
        checkAllTodos(done){
            this.todoArr.forEach(todo=>{
                todo.done=done
            })
        }
//MyFooter组件
<input type="checkbox" :checked="isAll" @change="checkAll">
props: ['todoArr','checkAllTodos'],
    methods:{
        checkAll(e){
            this.checkAllTodos(e.target.checked)
        }
    }

方案2:利用v-model

  1. 给复选框绑定v-model指令监听计算属性isAll
  2. 利用计算属性对isAll进行完整配置(包括set和get)
  3. get方法同上isAll方法
  4. set方法中调用App组件中传入的checkAllTodos方法
//App组件同上
//MyFooter组件
<input type="checkbox" v-model="isAll" >
        isAll:{
            get(){
                return this.total === this.doneTotal && this.total > 0
            },
            set(value){
                this.checkAllTodos(value)
            }
        }

清除已完成任务

与上方任务项删除思路、实现相似,代码略