一、需求描述
- 可以在最上面的任务栏输入任务,创建待办事项;
- 中间部分是展示任务,分为完成的任务以及未完成的任务;
- 下方可以看到是否全选以及完成个数,并可以清除所有已完成的任务;
- 目前有页面的html、css代码,要求完成交互功能。
二、组件分析
拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突。在本项目中,将组件分为“MyHeader.vue”,“MyList.vue”,“MyItem.vue”,“MyFooter.vue”,原因是Header是html中存在的标签名。
- “MyHeader.vue”:项目的头部,直接在App.vue中引入;
- “MyFooter.vue”:项目的底部,直接在App.vue中引入;
- “MyList.vue”:待办事项展示区域,直接在App.vue中引入;
-
“MyItem.vue”:每条任务展示,在MyList.vue中引入。
三、数据显示功能
- 由于List中的数据每个组件都要操作,因此将数据保存在App.vue中。同时考虑数据有id、名称、是否完成等属性,因此采用数组包裹对象的方式存储数据。
todos:[ {id:'001',title:'吃饭',checked:true}, {id:'002',title:'睡觉',checked:false}, {id:'003',title:'学习',checked:true}, {id:'004',title:'打豆豆',checked:false}, ]
- 要将数据传到MyList和MyItem中,MyList中应该是数组数据,MyItem中应该是单个的数据。
//MyList.vue <MyItem v-for="todo in this.todos" :key="todo.id" :todo="todo"/> //MyItem.vue <label> <input type="checkbox" :checked="todo.checked"/> //是否完成 <span>{{todo.title}}</span> //项目名称 </label>
- “是否点击”采用 :checked="todo.checked" 的原因是: checked后面应该是布尔值,若加上:则会将双引号中视为表达式进行计算,而数据中的checked的值便是布尔值。
四、添加任务功能
- 键盘功能,回车实现:@keyup.enter="add"。
- 随机生成id号:nanoid()。
import {nanoid} from 'nanoid' const id = nanoid();
- 已知父组件给子组件传递数据使用props,若要子组件给父组件传递数据,则需要父先给子一个函数,子的数据作为父的参数传回父进行运算,也要用props声明。
- 可以设置空字符串不得写入,重新写。
if(!e.target.value.trim()) return alert("待办项目不得为空,请重新输入")
五、更改选中功能
- 更改思路:获得选中事项id,遍历todos数组,修改id与获得id相同的事项,修改状态即可。
- JS中:forEach() 方法。
var numbers = [4, 9, 16, 25]; var sum = 0 //求和 numbers.forEach((n)=>{ //n是遍历出来的每一项 sum += n })
- 不要使用v-model同时绑定显示和更改事件,props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。
六、删除任务功能
- 删除思路:首先将代码中不显示删除的display删除,再获得点击id,todos中过滤掉id相同的事项。
- 过滤代码:
deleteTodo(id){ this.todos = this.todos.filter((todo)=>{ return todo.id !== id }) }
- 询问是否确认删除。
if(confirm('确定删除吗?')){ this.deleteTodo(this.todo.id) }
七、全选功能
- 全选思路:可以使用v-model双向传递数据,要修改todos数据时需要使用set()方法。
isAll:{ get(){ return this.allItem === this.getItem && this.allItem > 0 }, set(value){ this.clickAll(value) } }
- 使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的!
八、清除已完成任务功能
- 清除思路:过滤掉所有checked=true的事项。
clearTodo(){ this.todos = this.todos.filter((todo)=>{ return !todo.checked }) }