案例说明:
<br /> 
业务: 全选和反选功能:
1. 使用vue2的版本来完成
2. 使用vue3的版本来完成
目标功能:
- 渲染列表数据 v-for
 - 点击删除当前列表 splice + index
 - 回车添加新项目 @keyup.enter=”addTodo”list.unshift
 - 选择状态切换 v-model
 - 多选和取消多选 计算属性的set和get
 - 未完成任务数量统计 computed
 
 
vue2的版本
1. 模板
<template><section class="todoapp"><!-- 头部输入框区域 --><header class="header"><h1>todos</h1>// 第1个v-model: 这里是input输入框 v-model="flag"绑定的是用户输入的内容<input v-model="flag" class="new-todo" placeholder="请输入要完成的任务" autofocus@keyup.enter="hAdd" /></header><section class="main">// 第2个v-model: 全选切换的input v-model="isDoneAll" 绑定的是多选和取消多选的计算属性<input v-model="isDoneAll" id="toggle-all" class="toggle-all" type="checkbox" /><label for="toggle-all">标记所有已经完成</label><ul class="todo-list"><!-- 任务列表 --><li v-for="(item,idx) in list" :key="item.id"><div class="view">// 第3个v-model: v-model="item.isDone" 绑定的是状态的切换<input v-model="item.isDone" class="toggle" type="checkbox" checked /><label>{{item.flag}}</label><button class="destroy" @click="hDel(idx)"></button></div></li></ul></section><footer class="footer"><span class="todo-count">还未完成的任务有:<strong>{{isUnOk}}</strong>项</span></footer></section></template>
注意: 上面有3个v-model 弄清楚它们的用途
a) 第1个v-model: 这里是input输入框 v-model=”flag”绑定的是用户输入的内容
b) 第2个v-model: 全选切换input v-model=”isDoneAll” 绑定的是多选和取消多选的计算属性
c) 第3个v-model: v-model=”item.isDone” 绑定的是状态的切换
2. 完成的功能
data () {return {list: [{ id: 1, flag: '吃饭', isDone: true },{ id: 2, flag: '睡觉', isDone: false },{ id: 3, flag: '打豆豆', isDone: false },],flag: '', // 绑定的是输入框的内容}},// 核心代码computed: {// 计算属性监听选择状态 全选和反选的功能isDoneAll: {get () {return this.list.every(item => item.isDone === true)},set (val) {return this.list.forEach(item => item.isDone = val)}},// 计算属性统计未完成的数量isUnOk () {return this.list.filter(item => item.isDone === false).length}},methods: {// 删除hDel (idx) {this.list.splice(idx, 1)},// 按下回车新增// vue2的双向绑定input 就是在模板里面v-mdel="xxx" 然后在data中定义一下hAdd () {this.list.unshift({ id: Date.now, flag: this.flag, isDone: false })}}}
在上面中,这一步是全选和反选的关键步骤:
其他的代码我就不讲了 ,这里主要讲的就是如何完成全选和反选的功能

vue3版本
1. 模板
<template><section class="todoapp"><!-- 头部输入框区域 --><header class="header"><h1>todos</h1>// 第1个v-model: 这里是input输入框 v-model="flag"绑定的是用户输入的内容<input v-model="flag" class="new-todo" placeholder="请输入要完成的任务" autofocus@keyup.enter="hAdd" /></header><section class="main">// 第2个v-model: 全选切换的input v-model="isDoneAll" 绑定的是多选和取消多选的计算属性<input v-model="isDoneAll" @click="toggleAll" id="toggle-all" class="toggle-all" type="checkbox" /><label for="toggle-all">标记所有已经完成</label><ul class="todo-list"><!-- 任务列表 --><li v-for="(item,idx) in list" :key="item.id"><div class="view">// 第3个v-model: v-model="item.isDone" 绑定的是状态的切换<input v-model="item.isDone" class="toggle" type="checkbox" checked /><label>{{item.flag}}</label><button class="destroy" @click="hDel(idx)"></button></div></li></ul></section><footer class="footer"><span class="todo-count">还未完成的任务有:<strong>{{isUnOk}}</strong>项</span></footer></section></template>
注意: 这里和上面的vue2版本是一样的, 同样是绑定了3个v-model
2. 功能
import { computed, ref, watch } from 'vue'export default {setup () {// 定义数据const list = ref([{ id: 1, flag: '吃饭', isDone: true },{ id: 2, flag: '睡觉', isDone: true },{ id: 3, flag: '打豆豆', isDone: false },])// 点击删除当前的列表const hDel = idx => {list.value.splice(idx, 1)}// 注意区别vue2中的双向绑定 在vue3中如何做表单的双向绑定? 就是在模板中v-model="flag" 然后在下面定义一下const flag = ref('') 在新增里面 直接就是.value// 定义v-model绑定当前输入的内容// 模板中要绑定flag 实现响应式的const flag = ref('')// 回车事件里面 新增const hAdd = () => {list.value.unshift({id: Date.now(), flag: flag.value, isDone: false})}// 未完成的还有几项const unOkTodo = computed(() => {return list.value.filter(item => item.isDone === false).length})// 用watch监听来做 全选和反选let isDoneAll = ref(false)watch(list,(newValue) => {console.log(newValue.every((item) => item.isDone))if (newValue.every((item) => item.isDone)) {(isDoneAll.value = true)} else {(isDoneAll.value = false)}},{ immediate: true, deep: true })// 切换按钮const toggleAll = () => {if (!isDoneAll.value) {list.value.forEach(item => item.isDone = true)} else {list.value.forEach(item => item.isDone = false)}}return { list, hDel, flag, hAdd, unOkTodo, isDoneAll, toggleAll }}}
全选和反选的第1种方法: wacth 侦听器来完成
第2种方法: computed来完成

