(二十三)、todoList案列
1.案列_静态
(1).未拆分的静态资源
下面的数据直接复制:就行。博主没有进行修改或添加什么,和张天禹来时的静态资源一摸一样的。
App.vue
<template> <div> <div class="todo-container"> <div class="todo-wrap"> <!-- 1.头部 --> <div class="todo-header"> <input type="text" placeholder="请输入你的任务名称,按回车键确认"/> </div> <!-- 2.列表 --> <ul class="todo-main"> <li> <label> <input type="checkbox"/> <span>xxxxx</span> </label> <button class="btn btn-danger" style="display:none">删除</button> </li> <li> <label> <input type="checkbox"/> <span>yyyy</span> </label> <button class="btn btn-danger" style="display:none">删除</button> </li> </ul> <!-- 3.底部导航 --> <div class="todo-footer"> <label> <input type="checkbox"/> </label> <span> <span>已完成0</span> / 全部2 </span> <button class="btn btn-danger">清除已完成任务</button> </div> </div> </div> </div> </template> <script> export default { name:'App' // 目的是在浏览器VUE插件中的名字都是App不会被改变。 } </script> <style> /*base*/ body { background: #fff; } .btn { display: inline-block; padding: 4px 12px; margin-bottom: 0; font-size: 14px; line-height: 20px; text-align: center; vertical-align: middle; cursor: pointer; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); border-radius: 4px; } .btn-danger { color: #fff; background-color: #da4f49; border: 1px solid #bd362f; } .btn-danger:hover { color: #fff; background-color: #bd362f; } .btn:focus { outline: none; } .todo-container { width: 600px; margin: 0 auto; } .todo-container .todo-wrap { padding: 10px; border: 1px solid #ddd; border-radius: 5px; } /*header*/ .todo-header input { width: 560px; height: 28px; font-size: 14px; border: 1px solid #ccc; border-radius: 4px; padding: 4px 7px; } .todo-header input:focus { outline: none; border-color: rgba(82, 168, 236, 0.8); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); } /*list*/ .todo-main { margin-left: 0px; border: 1px solid #ddd; border-radius: 2px; padding: 0px; } .todo-empty { height: 40px; line-height: 40px; border: 1px solid #ddd; border-radius: 2px; padding-left: 5px; margin-top: 10px; } /*item*/ li { list-style: none; height: 36px; line-height: 36px; padding: 0 5px; border-bottom: 1px solid #ddd; } li label { float: left; cursor: pointer; } li label li input { vertical-align: middle; margin-right: 6px; position: relative; top: -1px; } li button { float: right; display: none; margin-top: 3px; } li:before { content: initial; } li:last-child { border-bottom: none; } /*footer*/ .todo-footer { height: 40px; line-height: 40px; padding-left: 6px; margin-top: 5px; } .todo-footer label { display: inline-block; margin-right: 20px; cursor: pointer; } .todo-footer label input { position: relative; top: -1px; vertical-align: middle; margin-right: 5px; } .todo-footer button { float: right; margin-top: 5px; } </style>
(2).拆分之后的静态资源
Header.vue
<template> <div> <!-- 1.头部 --> <div class="todo-header"> <input type="text" placeholder="请输入你的任务名称,按回车键确认"/> </div> </div> </template> <script> export default { name:'Header' } </script> <style scoped> /*header*/ .todo-header input { width: 560px; height: 28px; font-size: 14px; border: 1px solid #ccc; border-radius: 4px; padding: 4px 7px; } .todo-header input:focus { outline: none; border-color: rgba(82, 168, 236, 0.8); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); } </style>
List.vue
<template> <div> <ul class="todo-main"> <Item/> </ul> </div> </template> <script> import Item from './Item.vue' export default { name:'List', components:{ Item, } } </script> <style scoped> /*List*/ .todo-main { margin-left: 0px; border: 1px solid #ddd; border-radius: 2px; padding: 0px; } .todo-empty { height: 40px; line-height: 40px; border: 1px solid #ddd; border-radius: 2px; padding-left: 5px; margin-top: 10px; } </style>
Item.vue
<template> <div> <li> <label> <input type="checkbox"/> <span>xxxxx</span> </label> <button class="btn btn-danger" style="display:none">删除</button> </li> <li> <label> <input type="checkbox"/> <span>yyyy</span> </label> <button class="btn btn-danger" style="display:none">删除</button> </li> </div> </template> <script> export default { name:'Item' } </script> <style> /*item*/ li { list-style: none; height: 36px; line-height: 36px; padding: 0 5px; border-bottom: 1px solid #ddd; } li label { float: left; cursor: pointer; } li label li input { vertical-align: middle; margin-right: 6px; position: relative; top: -1px; } li button { float: right; display: none; margin-top: 3px; } li:before { content: initial; } li:last-child { border-bottom: none; } </style>
Footer.vue
<template> <div> <div class="todo-footer"> <label> <input type="checkbox"/> </label> <span> <span>已完成0</span> / 全部2 </span> <button class="btn btn-danger">清除已完成任务</button> </div> </div> </template> <script> export default { name:'Footer' } </script> <style scoped> /*footer*/ .todo-footer { height: 40px; line-height: 40px; padding-left: 6px; margin-top: 5px; } .todo-footer label { display: inline-block; margin-right: 20px; cursor: pointer; } .todo-footer label input { position: relative; top: -1px; vertical-align: middle; margin-right: 5px; } .todo-footer button { float: right; margin-top: 5px; } </style>
App.vue
<template> <div> <div class="todo-container"> <div class="todo-wrap"> <!-- 1.头部 --> <Header/> <!-- 2.列表 --> <list/> <!-- 3.底部导航 --> <Footer/> </div> </div> </div> </template> <script> // 1.引入 import Header from './components/Header.vue' import List from './components/List.vue' import Footer from './components/Footer.vue' export default { name:'App', // 目的是在浏览器VUE插件中的名字都是App不会被改变。 // 2.注册 components:{ Header, List, Footer } } </script> <style> /*base*/ body { background: #fff; } .btn { display: inline-block; padding: 4px 12px; margin-bottom: 0; font-size: 14px; line-height: 20px; text-align: center; vertical-align: middle; cursor: pointer; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); border-radius: 4px; } .btn-danger { color: #fff; background-color: #da4f49; border: 1px solid #bd362f; } .btn-danger:hover { color: #fff; background-color: #bd362f; } .btn:focus { outline: none; } .todo-container { width: 600px; margin: 0 auto; } .todo-container .todo-wrap { padding: 10px; border: 1px solid #ddd; border-radius: 5px; } </style>
2.案列_初始化数据 (父App.vue传递数组)
(1).利用props接受父App.vue传过来的数据
引用父类传递给子类的数据的时候,一定要添加上this.(父类传递的数据)
切记一句话,数据源在哪,就在哪里做增删改查,子类需要通知父App.vue.然后父App.vue进行真实的增删改查
1.App.vue
<template> <div> <div class="todo-container"> <div class="todo-wrap"> <!-- 1.头部 --> <Header/> <!-- 2.列表 --> <list :todosA="todos"/> <!-- 3.底部导航 --> <Footer/> </div> </div> </div> </template> <script> // 1.引入组件 import Header from './components/Header.vue' import List from './components/List.vue' import Footer from './components/Footer.vue' export default { name:'App', // 目的是在浏览器VUE插件中的名字都是App不会被改变。 // 2.注册组件 components:{ Header, List, Footer }, data() { return { todos:[ {id:'001',name:'抽烟',done:true}, {id:'002',name:'喝酒',done:false}, {id:'003',name:'烫头',done:true} ] } }, } </script> <style> /*base*/ body { background: #fff; } .btn { display: inline-block; padding: 4px 12px; margin-bottom: 0; font-size: 14px; line-height: 20px; text-align: center; vertical-align: middle; cursor: pointer; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); border-radius: 4px; } .btn-danger { color: #fff; background-color: #da4f49; border: 1px solid #bd362f; } .btn-danger:hover { color: #fff; background-color: #bd362f; } .btn:focus { outline: none; } .todo-container { width: 600px; margin: 0 auto; } .todo-container .todo-wrap { padding: 10px; border: 1px solid #ddd; border-radius: 5px; } </style>
2.List.vue: 接受父App.vue传递的参数并遍历我们传入的数据
1.一定要存在 :key否则会报错。 <Item v-for="t in this.todosA" :key="t.id"/> 2.将数据传递给Item.vue子组件 <Item v-for="t in this.todosA" :key="t.id" :itemA="t"/>
<template> <div> <ul class="todo-main"> <!-- 这里我们必须需要添加key。 并向Item.vue传递遍历的对象t--> <<Item v-for="t in this.todosA" :key="t.id" :itemA="t"/> </ul> </div> </template> <script> import Item from './Item.vue' export default { name:'List', components:{ Item, }, props:['todosA'], // 负责声明接受且不做限制... } </script> <style scoped> /*List*/ .todo-main { margin-left: 0px; border: 1px solid #ddd; border-radius: 2px; padding: 0px; } .todo-empty { height: 40px; line-height: 40px; border: 1px solid #ddd; border-radius: 2px; padding-left: 5px; margin-top: 10px; } </style>
3.Item.vue: 接受父List.vue的传递的参数并赋值
<template> <div> <li> <label> <input type="checkbox" :checked="itemA.done"/> <span>{{itemA.name}}</span> </label> <button class="btn btn-danger" style="display:none">删除</button> </li> </div> </template> <script> export default { name:'Item', props:['itemA'] } </script> <style> /*item*/ li { list-style: none; height: 36px; line-height: 36px; padding: 0 5px; border-bottom: 1px solid #ddd; } li label { float: left; cursor: pointer; } li label li input { vertical-align: middle; margin-right: 6px; position: relative; top: -1px; } li button { float: right; display: none; margin-top: 3px; } li:before { content: initial; } li:last-child { border-bottom: none; } </style>
3.案列_添加todo (父APP.vue传递方法)
当我们在输入框输入文字之后,然后按下回车键。就在列表中添加数据。子类调用父类的时候一定要使用this.父类传递来的方法
Header.vue
<template> <div> <!-- 1.头部 --> <div class="todo-header"> <input type="text" placeholder="请输入你的任务名称,按回车键确认" v-model="textA" @keyup.enter="add"/> </div> </div> </template> <script> export default { name:'Header', data() { return { textA:'' } }, methods: { add(){ if(this.textA!==null){ // 根据用户的输入生成一个todo对象 const todo={id:Date.now(),name:this.textA,done:false} // 通知父App.vue添加这个数据 this.addFatherA(todo) } this.textA='' } }, // 接受父APP.vue传递过来的方法 props:['addFatherA'] } </script> <style scoped> /*header*/ .todo-header input { width: 560px; height: 28px; font-size: 14px; border: 1px solid #ccc; border-radius: 4px; padding: 4px 7px; } .todo-header input:focus { outline: none; border-color: rgba(82, 168, 236, 0.8); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); } </style>
App.vue
<template> <div> <div class="todo-container"> <div class="todo-wrap"> <!-- 1.头部 将父APP.VUE的addFather方法传递给子组件--> <Header :addFatherA="addFather"/> <!-- 2.列表 : 将父APP.VUE的todos数组传递给子组件--> <list :todosA="todos"/> <!-- 3.底部导航 --> <Footer/> </div> </div> </div> </template> <script> // 1.引入组件 import Header from './components/Header.vue' import List from './components/List.vue' import Footer from './components/Footer.vue' export default { name:'App', // 目的是在浏览器VUE插件中的名字都是App不会被改变。 // 2.注册组件 components:{ Header, List, Footer }, data() { return { todos:[ {id:'001',name:'抽烟',done:true}, {id:'002',name:'喝酒',done:false}, {id:'003',name:'烫头',done:true} ] } }, methods: { addFather(todoObj){ // 这个方法是对todos这个数组的尾部追加对象todoObj this.todos.unshift(todoObj) } }, } </script> <style> /*base*/ body { background: #fff; } .btn { display: inline-block; padding: 4px 12px; margin-bottom: 0; font-size: 14px; line-height: 20px; text-align: center; vertical-align: middle; cursor: pointer; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); border-radius: 4px; } .btn-danger { color: #fff; background-color: #da4f49; border: 1px solid #bd362f; } .btn-danger:hover { color: #fff; background-color: #bd362f; } .btn:focus { outline: none; } .todo-container { width: 600px; margin: 0 auto; } .todo-container .todo-wrap { padding: 10px; border: 1px solid #ddd; border-radius: 5px; } </style>
4.案列_Item高亮
(1).鼠标到达的地方出现残影
1. 利用三元运算符进行残影的确定。 <li @mouseenter="isEnter=true" @mouseleave="isEnter=false" :class="isEnter ? 'high_light' : ''"> 2.知道样式却不知道用不用 <li @mouseenter="isEnter=true" @mouseleave="isEnter=false" :class="{'high_light':isEnter}">
<template> <div> <!-- 鼠标进入与鼠标移除的值是: boolean值。 利用三元运算符进行判定是否使用样式 --> <!-- <li @mouseenter="isEnter=true" @mouseleave="isEnter=false" :class="isEnter ? 'high_light' : ''"> --> <li @mouseenter="isEnter=true" @mouseleave="isEnter=false" :class="{'high_light':isEnter}"> <label> <input type="checkbox" :checked="this.itemA.done"/> <span>{{this.itemA.name}}</span> </label> <button class="btn btn-danger" style="display:none">删除</button> </li> </div> </template> <script> export default { name:'Item', props:['itemA'], data() { return { isEnter:false // 标识鼠标是否移入 } }, } </script> <style> /*item*/ li { list-style: none; height: 36px; line-height: 36px; padding: 0 5px; border-bottom: 1px solid #ddd; } li label { float: left; cursor: pointer; } li label li input { vertical-align: middle; margin-right: 6px; position: relative; top: -1px; } li button { float: right; display: none; margin-top: 3px; } li:before { content: initial; } li:last-child { border-bottom: none; } .high_light { background-color: bisque; } </style>
(2).鼠标达到的地方出现残影+按钮展现
如果样式里面是: 用的是对象那么有下划线的地方需要使用单引号。否则可以省略,但建议都加上单引号
<!-- 想要动态的处理一定要进行 : 然后利用三元运算符进行判断是否要展示按钮block展示,none不展示--> <button class="btn btn-danger" :style="{'display':isEnter ? 'block' : 'none'}">删除</button>
<template> <div> <!-- 鼠标进入与鼠标移除的值是: boolean值。 利用三元运算符进行判定是否使用样式 --> <!-- <li @mouseenter="isEnter=true" @mouseleave="isEnter=false" :class="isEnter ? 'high_light' : ''"> --> <li @mouseenter="isEnter=true" @mouseleave="isEnter=false" :class="{'high_light':isEnter}"> <label> <input type="checkbox" :checked="this.itemA.done"/> <span>{{this.itemA.name}}</span> </label> <!-- 想要动态的处理一定要进行 : 然后利用三元运算符进行判断是否要展示按钮block展示,none不展示--> <button class="btn btn-danger" :style="{'display':isEnter ? 'block' : 'none'}">删除</button> </li> </div> </template> <script> export default { name:'Item', props:['itemA'], data() { return { isEnter:false // 标识鼠标是否移入 } }, } </script> <style> /*item*/ li { list-style: none; height: 36px; line-height: 36px; padding: 0 5px; border-bottom: 1px solid #ddd; } li label { float: left; cursor: pointer; } li label li input { vertical-align: middle; margin-right: 6px; position: relative; top: -1px; } li button { float: right; display: none; margin-top: 3px; } li:before { content: initial; } li:last-child { border-bottom: none; } .high_light { background-color: bisque; } </style>
5.案列_勾选todo
(1).利用id去更新一个数组
Item.vue
主要负责通知App.vue和接受App.vue传递过来的方法
updateFather(id,doneA){ // 利用map遍历数组todos,获取到的分别是数组对象和对象坐标 this.todos=this.todos.map((value,index)=>{ // 这里的this是window,匿名 if(id===value.id){ // 假如说子类传递过来的值和map遍历的值一样,那么就返回 所有的属性+修改后的值 return {...value,done:doneA} }else{ return value } }) }
<template> <div> <!-- 鼠标进入与鼠标移除的值是: boolean值。 利用三元运算符进行判定是否使用样式 --> <!-- <li @mouseenter="isEnter=true" @mouseleave="isEnter=false" :class="isEnter ? 'high_light' : ''"> --> <li @mouseenter="isEnter=true" @mouseleave="isEnter=false" :class="{'high_light':isEnter}"> <label> <input type="checkbox" :checked="this.itemA.done" @click="update(itemA.id,$event)"/> <span>{{this.itemA.name}}</span> </label> <!-- 想要动态的处理一定要进行 : 然后利用三元运算符进行判断是否要展示按钮block展示,none不展示--> <button class="btn btn-danger" :style="{'display':isEnter ? 'block' : 'none'}">删除</button> </li> </div> </template> <script> export default { name:'Item', props:['itemA','updateFatherB'], data() { return { isEnter:false // 标识鼠标是否移入 } }, methods: { update(id,event){ // 获取勾选的id 和勾选的值。这里因为属性是checked所以我们获取到的应该是checked而不是value。 console.log(id,event.target.checked); // 2.通知父App.vue this.updateFatherB(id,event.target.checked) } }, } </script> <style> /*item*/ li { list-style: none; height: 36px; line-height: 36px; padding: 0 5px; border-bottom: 1px solid #ddd; } li label { float: left; cursor: pointer; } li label li input { vertical-align: middle; margin-right: 6px; position: relative; top: -1px; } li button { float: right; display: none; margin-top: 3px; } li:before { content: initial; } li:last-child { border-bottom: none; } .high_light { background-color: bisque; } </style>
App.vue
主要负责给子类List.vue传递勾选的方法
<template> <div> <div class="todo-container"> <div class="todo-wrap"> <!-- 1.头部 将父APP.VUE的addFather方法传递给子组件--> <Header :addFatherA="addFather"/> <!-- 2.列表 : 将父APP.VUE的todos数组传递给子组件--> <list :todosA="todos" :updateFatherA="updateFather"/> <!-- 3.底部导航 --> <Footer/> </div> </div> </div> </template> <script> // 1.引入组件 import Header from './components/Header.vue' import List from './components/List.vue' import Footer from './components/Footer.vue' export default { name:'App', // 目的是在浏览器VUE插件中的名字都是App不会被改变。 // 2.注册组件 components:{ Header, List, Footer }, data() { return { todos:[ {id:'001',name:'抽烟',done:true}, {id:'002',name:'喝酒',done:false}, {id:'003',name:'烫头',done:true} ] } }, methods: { addFather(todoObj){ // 这个方法是对todos这个数组的尾部追加对象todoObj this.todos.unshift(todoObj) }, updateFather(id,doneA){ // 利用map遍历数组todos,获取到的分别是数组对象和对象坐标 this.todos=this.todos.map((value,index)=>{ if(id===value.id){ // 假如说子类传递过来的值和map遍历的值一样,那么就返回 所有的属性+修改后的值 return {...value,done:doneA} }else{ return value } }) } }, } </script> <style> /*base*/ body { background: #fff; } .btn { display: inline-block; padding: 4px 12px; margin-bottom: 0; font-size: 14px; line-height: 20px; text-align: center; vertical-align: middle; cursor: pointer; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); border-radius: 4px; } .btn-danger { color: #fff; background-color: #da4f49; border: 1px solid #bd362f; } .btn-danger:hover { color: #fff; background-color: #bd362f; } .btn:focus { outline: none; } .todo-container { width: 600px; margin: 0 auto; } .todo-container .todo-wrap { padding: 10px; border: 1px solid #ddd; border-radius: 5px; } </style>
List.vue
主要负责当桥梁因为父App.vue不能直接传递给Item.vue。需要借助List.vue传递给Item.vue
<template> <div> <ul class="todo-main"> <!-- 这里我们必须需要添加key --> <Item v-for="t in this.todosA" :key="t.id" :itemA="t" :updateFatherB="updateFatherA"/> </ul> </div> </template> <script> import Item from './Item.vue' export default { name:'List', components:{ Item, }, // 接受更新的函数 props:['todosA','updateFatherA'], // 负责声明接受且不做限制... } </script> <style scoped> /*List*/ .todo-main { margin-left: 0px; border: 1px solid #ddd; border-radius: 2px; padding: 0px; } .todo-empty { height: 40px; line-height: 40px; border: 1px solid #ddd; border-radius: 2px; padding-left: 5px; margin-top: 10px; } </style>
(2).利用index去更新一个数组
App.vue
<template> <div> <div class="todo-container"> <div class="todo-wrap"> <!-- 1.头部 将父APP.VUE的addFather方法传递给子组件--> <Header :addFatherA="addFather"/> <!-- 2.列表 : 将父APP.VUE的todos数组传递给子组件--> <list :todosA="todos" :updateFatherA="updateFather"/> <!-- 3.底部导航 --> <Footer/> </div> </div> </div> </template> <script> // 1.引入组件 import Header from './components/Header.vue' import List from './components/List.vue' import Footer from './components/Footer.vue' export default { name:'App', // 目的是在浏览器VUE插件中的名字都是App不会被改变。 // 2.注册组件 components:{ Header, List, Footer }, data() { return { todos:[ {id:'001',name:'抽烟',done:true}, {id:'002',name:'喝酒',done:false}, {id:'003',name:'烫头',done:true} ] } }, methods: { addFather(todoObj){ // 这个方法是对todos这个数组的尾部追加对象todoObj this.todos.unshift(todoObj) }, /* 利用id updateFather(id,doneA){ // 利用map遍历数组todos,获取到的分别是数组对象和对象坐标 this.todos=this.todos.map((value,index)=>{ if(id===value.id){ // 假如说子类传递过来的值和map遍历的值一样,那么就返回 所有的属性+修改后的值 return {...value,done:doneA} }else{ return value } }) } */ updateFather(index,doneA){ this.todos[index].done=doneA } }, } </script> <style> /*base*/ body { background: #fff; } .btn { display: inline-block; padding: 4px 12px; margin-bottom: 0; font-size: 14px; line-height: 20px; text-align: center; vertical-align: middle; cursor: pointer; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); border-radius: 4px; } .btn-danger { color: #fff; background-color: #da4f49; border: 1px solid #bd362f; } .btn-danger:hover { color: #fff; background-color: #bd362f; } .btn:focus { outline: none; } .todo-container { width: 600px; margin: 0 auto; } .todo-container .todo-wrap { padding: 10px; border: 1px solid #ddd; border-radius: 5px; } </style>
List.vue
在遍历的时候: 我们添加一个index.并且将这个index传递给Item.vue • 1
<template> <div> <ul class="todo-main"> <!-- 这里我们必须需要添加key --> <Item v-for="(t,index) in this.todosA" :key="t.id" :itemA="t" :updateFatherB="updateFatherA" :indexB="index" /> </ul> </div> </template> <script> import Item from './Item.vue' export default { name:'List', components:{ Item, }, // 接受更新的函数 props:['todosA','updateFatherA'], // 负责声明接受且不做限制... } </script> <style scoped> /*List*/ .todo-main { margin-left: 0px; border: 1px solid #ddd; border-radius: 2px; padding: 0px; } .todo-empty { height: 40px; line-height: 40px; border: 1px solid #ddd; border-radius: 2px; padding-left: 5px; margin-top: 10px; } </style>
Item.vue
接受传递过来的index,并通知父App.vue
<template> <div> <!-- 鼠标进入与鼠标移除的值是: boolean值。 利用三元运算符进行判定是否使用样式 --> <!-- <li @mouseenter="isEnter=true" @mouseleave="isEnter=false" :class="isEnter ? 'high_light' : ''"> --> <li @mouseenter="isEnter=true" @mouseleave="isEnter=false" :class="{'high_light':isEnter}"> <label> <input type="checkbox" :checked="this.itemA.done" @click="update(indexB,$event)"/> <span>{{this.itemA.name}}</span> </label> <!-- 想要动态的处理一定要进行 : 然后利用三元运算符进行判断是否要展示按钮block展示,none不展示--> <button class="btn btn-danger" :style="{'display':isEnter ? 'block' : 'none'}">删除</button> </li> </div> </template> <script> export default { name:'Item', props:['itemA','updateFatherB','indexB'], data() { return { isEnter:false // 标识鼠标是否移入 } }, methods: { /* 利用id update(id,event){ // 获取勾选的id 和勾选的值。这里因为属性是checked所以我们获取到的应该是checked而不是value。 console.log(id,event.target.checked); // 2.通知父App.vue this.updateFatherB(id,event.target.checked) }*/ // 利用index update(index,event){ // 获取勾选的id 和勾选的值。这里因为属性是checked所以我们获取到的应该是checked而不是value。 console.log(index,event.target.checked); // 2.通知父App.vue this.updateFatherB(index,event.target.checked) } }, } </script> <style> /*item*/ li { list-style: none; height: 36px; line-height: 36px; padding: 0 5px; border-bottom: 1px solid #ddd; } li label { float: left; cursor: pointer; } li label li input { vertical-align: middle; margin-right: 6px; position: relative; top: -1px; } li button { float: right; display: none; margin-top: 3px; } li:before { content: initial; } li:last-child { border-bottom: none; } .high_light { background-color: bisque; } </style>
(3).利用v-model更新数组
- 发现控制台输出的数据和实质不一样 ⭐
// 利用index update(index,event){ // 获取勾选的id 和勾选的值。这里因为属性是checked所以我们获取到的应该是checked而不是value。 console.log(index,this.isChecked); // 2.通知父App.vue this.updateFatherB(index,event.target.checked) }
<template> <div> <!-- 鼠标进入与鼠标移除的值是: boolean值。 利用三元运算符进行判定是否使用样式 --> <!-- <li @mouseenter="isEnter=true" @mouseleave="isEnter=false" :class="isEnter ? 'high_light' : ''"> --> <li @mouseenter="isEnter=true" @mouseleave="isEnter=false" :class="{'high_light':isEnter}"> <label> <input type="checkbox" v-model="isChecked" @click="update(indexB,$event)"/> <span>{{this.itemA.name}}</span> </label> <!-- 想要动态的处理一定要进行 : 然后利用三元运算符进行判断是否要展示按钮block展示,none不展示--> <button class="btn btn-danger" :style="{'display':isEnter ? 'block' : 'none'}">删除</button> </li> </div> </template> <script> export default { name:'Item', props:['itemA','updateFatherB','indexB'], data() { return { isEnter:false, // 标识鼠标是否移入 isChecked:this.itemA.done } }, methods: { /* 利用id update(id,event){ // 获取勾选的id 和勾选的值。这里因为属性是checked所以我们获取到的应该是checked而不是value。 console.log(id,event.target.checked); // 2.通知父App.vue this.updateFatherB(id,event.target.checked) }*/ // 利用index update(index,event){ // 获取勾选的id 和勾选的值。这里因为属性是checked所以我们获取到的应该是checked而不是value。 console.log(index,this.isChecked); // 2.通知父App.vue this.updateFatherB(index,event.target.checked) } }, } </script> <style> /*item*/ li { list-style: none; height: 36px; line-height: 36px; padding: 0 5px; border-bottom: 1px solid #ddd; } li label { float: left; cursor: pointer; } li label li input { vertical-align: middle; margin-right: 6px; position: relative; top: -1px; } li button { float: right; display: none; margin-top: 3px; } li:before { content: initial; } li:last-child { border-bottom: none; } .high_light { background-color: bisque; } </style>
- 解决控制台输出的数据和实质不一样 ⭐
原因是vue事件优先,所以点击事件先被调用之后,才是model
直接打印出事件的值而不是data区域的数据 // 利用index update(index,event){ // 获取勾选的id 和勾选的值。这里因为属性是checked所以我们获取到的应该是checked而不是value。 console.log(index,event.target.checked); // 2.通知父App.vue this.updateFatherB(index,event.target.checked) }
<template> <div> <!-- 鼠标进入与鼠标移除的值是: boolean值。 利用三元运算符进行判定是否使用样式 --> <!-- <li @mouseenter="isEnter=true" @mouseleave="isEnter=false" :class="isEnter ? 'high_light' : ''"> --> <li @mouseenter="isEnter=true" @mouseleave="isEnter=false" :class="{'high_light':isEnter}"> <label> <input type="checkbox" v-model="isChecked" @click="update(indexB,$event)"/> <span>{{this.itemA.name}}</span> </label> <!-- 想要动态的处理一定要进行 : 然后利用三元运算符进行判断是否要展示按钮block展示,none不展示--> <button class="btn btn-danger" :style="{'display':isEnter ? 'block' : 'none'}">删除</button> </li> </div> </template> <script> export default { name:'Item', props:['itemA','updateFatherB','indexB'], data() { return { isEnter:false, // 标识鼠标是否移入 isChecked:this.itemA.done } }, methods: { /* 利用id update(id,event){ // 获取勾选的id 和勾选的值。这里因为属性是checked所以我们获取到的应该是checked而不是value。 console.log(id,event.target.checked); // 2.通知父App.vue this.updateFatherB(id,event.target.checked) }*/ // 利用index update(index,event){ // 获取勾选的id 和勾选的值。这里因为属性是checked所以我们获取到的应该是checked而不是value。 console.log(index,event.target.checked); // 2.通知父App.vue this.updateFatherB(index,event.target.checked) } }, } </script> <style> /*item*/ li { list-style: none; height: 36px; line-height: 36px; padding: 0 5px; border-bottom: 1px solid #ddd; } li label { float: left; cursor: pointer; } li label li input { vertical-align: middle; margin-right: 6px; position: relative; top: -1px; } li button { float: right; display: none; margin-top: 3px; } li:before { content: initial; } li:last-child { border-bottom: none; } .high_light { background-color: bisque; } </style>
6.案列_删除
App.vue: 传递给List.vue删除的方法"
deleteFather(index){ // 根据坐标删除数据 this.todos.splice(index,1) }
<template> <div> <div class="todo-container"> <div class="todo-wrap"> <!-- 1.头部 将父APP.VUE的addFather方法传递给子组件--> <Header :addFatherA="addFather"/> <!-- 2.列表 : 将父APP.VUE的todos数组传递给子组件--> <list :todosA="todos" :updateFatherA="updateFather" :deleteFatherA="deleteFather" /> <!-- 3.底部导航 --> <Footer/> </div> </div> </div> </template> <script> // 1.引入组件 import Header from './components/Header.vue' import List from './components/List.vue' import Footer from './components/Footer.vue' export default { name:'App', // 目的是在浏览器VUE插件中的名字都是App不会被改变。 // 2.注册组件 components:{ Header, List, Footer }, data() { return { todos:[ {id:'001',name:'抽烟',done:true}, {id:'002',name:'喝酒',done:false}, {id:'003',name:'烫头',done:true} ] } }, methods: { addFather(todoObj){ // 这个方法是对todos这个数组的尾部追加对象todoObj this.todos.unshift(todoObj) }, /* 利用id updateFather(id,doneA){ // 利用map遍历数组todos,获取到的分别是数组对象和对象坐标 this.todos=this.todos.map((value,index)=>{ if(id===value.id){ // 假如说子类传递过来的值和map遍历的值一样,那么就返回 所有的属性+修改后的值 return {...value,done:doneA} }else{ return value } }) } */ updateFather(index,doneA){ this.todos[index].done=doneA }, deleteFather(index){ // 根据坐标删除数据 this.todos.splice(index,1) } }, } </script> <style> /*base*/ body { background: #fff; } .btn { display: inline-block; padding: 4px 12px; margin-bottom: 0; font-size: 14px; line-height: 20px; text-align: center; vertical-align: middle; cursor: pointer; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); border-radius: 4px; } .btn-danger { color: #fff; background-color: #da4f49; border: 1px solid #bd362f; } .btn-danger:hover { color: #fff; background-color: #bd362f; } .btn:focus { outline: none; } .todo-container { width: 600px; margin: 0 auto; } .todo-container .todo-wrap { padding: 10px; border: 1px solid #ddd; border-radius: 5px; } </style>
List.vue: 传递给Item.vue的删除方法
<template> <div> <ul class="todo-main"> <!-- 这里我们必须需要添加key --> <Item v-for="(t,index) in this.todosA" :key="t.id" :itemA="t" :updateFatherB="updateFatherA" :indexB="index" :deleteFatherB="deleteFatherA" /> </ul> </div> </template> <script> import Item from './Item.vue' export default { name:'List', components:{ Item, }, // 接受更新的函数 props:['todosA','updateFatherA','deleteFatherA'], // 负责声明接受且不做限制... } </script> <style scoped> /*List*/ .todo-main { margin-left: 0px; border: 1px solid #ddd; border-radius: 2px; padding: 0px; } .todo-empty { height: 40px; line-height: 40px; border: 1px solid #ddd; border-radius: 2px; padding-left: 5px; margin-top: 10px; } </style>
Item.vue: 通知父App.vue传进来一个删除的方法
<template> <div> <ul class="todo-main"> <!-- 这里我们必须需要添加key --> <Item v-for="(t,index) in this.todosA" :key="t.id" :itemA="t" :updateFatherB="updateFatherA" :indexB="index" :deleteFatherB="deleteFatherA" /> </ul> </div> </template> <script> import Item from './Item.vue' export default { name:'List', components:{ Item, }, // 接受更新的函数 props:['todosA','updateFatherA','deleteFatherA'], // 负责声明接受且不做限制... } </script> <style scoped> /*List*/ .todo-main { margin-left: 0px; border: 1px solid #ddd; border-radius: 2px; padding: 0px; } .todo-empty { height: 40px; line-height: 40px; border: 1px solid #ddd; border-radius: 2px; padding-left: 5px; margin-top: 10px; } </style>
7.案列_全选
(1).案列总数与已选总数
App.vue传递Footer.vue数组
<!-- 3.底部导航 --> <Footer :FooterTodos="todos"/>
<template> <div> <div class="todo-container"> <div class="todo-wrap"> <!-- 1.头部 将父APP.VUE的addFather方法传递给子组件--> <Header :addFatherA="addFather"/> <!-- 2.列表 : 将父APP.VUE的todos数组传递给子组件--> <list :todosA="todos" :updateFatherA="updateFather" :deleteFatherA="deleteFather" /> <!-- 3.底部导航 --> <Footer :FooterTodos="todos"/> </div> </div> </div> </template> <script> // 1.引入组件 import Header from './components/Header.vue' import List from './components/List.vue' import Footer from './components/Footer.vue' export default { name:'App', // 目的是在浏览器VUE插件中的名字都是App不会被改变。 // 2.注册组件 components:{ Header, List, Footer }, data() { return { todos:[ {id:'001',name:'抽烟',done:true}, {id:'002',name:'喝酒',done:false}, {id:'003',name:'烫头',done:true} ] } }, methods: { addFather(todoObj){ // 这个方法是对todos这个数组的尾部追加对象todoObj this.todos.unshift(todoObj) }, /* 利用id updateFather(id,doneA){ // 利用map遍历数组todos,获取到的分别是数组对象和对象坐标 this.todos=this.todos.map((value,index)=>{ if(id===value.id){ // 假如说子类传递过来的值和map遍历的值一样,那么就返回 所有的属性+修改后的值 return {...value,done:doneA} }else{ return value } }) } */ updateFather(index,doneA){ this.todos[index].done=doneA }, deleteFather(index){ // 根据坐标删除数据 this.todos.splice(index,1) } }, } </script> <style> /*base*/ body { background: #fff; } .btn { display: inline-block; padding: 4px 12px; margin-bottom: 0; font-size: 14px; line-height: 20px; text-align: center; vertical-align: middle; cursor: pointer; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); border-radius: 4px; } .btn-danger { color: #fff; background-color: #da4f49; border: 1px solid #bd362f; } .btn-danger:hover { color: #fff; background-color: #bd362f; } .btn:focus { outline: none; } .todo-container { width: 600px; margin: 0 auto; } .todo-container .todo-wrap { padding: 10px; border: 1px solid #ddd; border-radius: 5px; } </style>
Footer.vue
利用计算属性: 获取总数和 computed:{ doneCount(){ // 数组的所有方法以及定时函数的所有方法都是归window管理的 // 数组.reduce(累加数据,初始值) js自带的累加器 return this.FooterTodos.reduce((pre,current)=>pre+=current.done ? 1: 0,0) // 匿名方法的参数:(上次调用函数的返回值,当前元素) }, total(){ return this.FooterTodos.length; } }
<template> <div> <div class="todo-footer"> <label> <input type="checkbox"/> </label> <span> <span>已完成{{doneCount}}</span> / 全部{{total}} </span> <button class="btn btn-danger">清除已完成任务</button> </div> </div> </template> <script> export default { name:'Footer', // 声明 props:['FooterTodos'], // 1.利用计算属性进行获取已完成 computed:{ doneCount(){ // 数组的所有方法以及定时函数的所有方法都是归window管理的 // 数组.reduce(累加数据,初始值) js自带的累加器 return this.FooterTodos.reduce((pre,current)=>pre+=current.done ? 1: 0,0) // 匿名方法的参数:(上次调用函数的返回值,当前元素) }, total(){ return this.FooterTodos.length; } } } </script> <style scoped> /*footer*/ .todo-footer { height: 40px; line-height: 40px; padding-left: 6px; margin-top: 5px; } .todo-footer label { display: inline-block; margin-right: 20px; cursor: pointer; } .todo-footer label input { position: relative; top: -1px; vertical-align: middle; margin-right: 5px; } .todo-footer button { float: right; margin-top: 5px; } </style>
(2).案列全选
App.vue: 传递一个方法
<template> <div> <div class="todo-container"> <div class="todo-wrap"> <!-- 1.头部 将父APP.VUE的addFather方法传递给子组件--> <Header :addFatherA="addFather"/> <!-- 2.列表 : 将父APP.VUE的todos数组传递给子组件--> <list :todosA="todos" :updateFatherA="updateFather" :deleteFatherA="deleteFather" /> <!-- 3.底部导航 --> <Footer :FooterTodos="todos" :updateAllFatherA="updateAllFather" /> </div> </div> </div> </template> <script> // 1.引入组件 import Header from './components/Header.vue' import List from './components/List.vue' import Footer from './components/Footer.vue' export default { name:'App', // 目的是在浏览器VUE插件中的名字都是App不会被改变。 // 2.注册组件 components:{ Header, List, Footer }, data() { return { todos:[ {id:'001',name:'抽烟',done:true}, {id:'002',name:'喝酒',done:false}, {id:'003',name:'烫头',done:true} ] } }, methods: { addFather(todoObj){ // 这个方法是对todos这个数组的尾部追加对象todoObj this.todos.unshift(todoObj) }, /* 利用id updateFather(id,doneA){ // 利用map遍历数组todos,获取到的分别是数组对象和对象坐标 this.todos=this.todos.map((value,index)=>{ if(id===value.id){ // 假如说子类传递过来的值和map遍历的值一样,那么就返回 所有的属性+修改后的值 return {...value,done:doneA} }else{ return value } }) } */ // 更新 updateFather(index,doneA){ this.todos[index].done=doneA }, // 删除 deleteFather(index){ // 根据坐标删除数据 this.todos.splice(index,1) }, // 全选或者不选 updateAllFather(doneOption){ // map():创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。 this.todos=this.todos.map((value)=>{ // 这个参数是遍历的单个对象 return {...value,done:doneOption} // 返回将done属性改编为doneOption的完整对象 }) } }, } </script> <style> /*base*/ body { background: #fff; } .btn { display: inline-block; padding: 4px 12px; margin-bottom: 0; font-size: 14px; line-height: 20px; text-align: center; vertical-align: middle; cursor: pointer; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); border-radius: 4px; } .btn-danger { color: #fff; background-color: #da4f49; border: 1px solid #bd362f; } .btn-danger:hover { color: #fff; background-color: #bd362f; } .btn:focus { outline: none; } .todo-container { width: 600px; margin: 0 auto; } .todo-container .todo-wrap { padding: 10px; border: 1px solid #ddd; border-radius: 5px; } </style>
Footer.vue: 接受一个方法
// 计算属性是顺序的,也就是可以套娃 isAll:{ // 全选的效果 set(flag){ //获取到的是一个布尔值 console.log(flag) // 通知父App.vue传递方法 return this.updateAllFatherA(flag) }, // get(){ return this.doneCount===this.total && this.total>0 }
<template> <div> <div class="todo-footer"> <label> <!-- 类型为checkbox 的值是布尔值 --> <input type="checkbox" v-model="isAll"/> </label> <span> <span>已完成{{doneCount}}</span> / 全部{{total}} </span> <button class="btn btn-danger">清除已完成任务</button> </div> </div> </template> <script> export default { name:'Footer', // 声明 props:['FooterTodos','updateAllFatherA'], // 1.利用计算属性进行获取已完成 computed:{ // 被选择的 doneCount(){ // 数组的所有方法以及定时函数的所有方法都是归window管理的 // 数组.reduce(累加数据,初始值) js自带的累加器 return this.FooterTodos.reduce((pre,current)=>pre+=current.done ? 1: 0,0) // 匿名方法的参数:(上次调用函数的返回值,当前元素) }, // 总数 total(){ return this.FooterTodos.length; }, // 计算属性是顺序的,也就是可以套娃 isAll:{ // 全选的效果 set(flag){ //获取到的是一个布尔值 console.log(flag) // 通知父App.vue传递方法 return this.updateAllFatherA(flag) }, // get(){ return this.doneCount===this.total && this.total>0 } } } } </script> <style scoped> /*footer*/ .todo-footer { height: 40px; line-height: 40px; padding-left: 6px; margin-top: 5px; } .todo-footer label { display: inline-block; margin-right: 20px; cursor: pointer; } .todo-footer label input { position: relative; top: -1px; vertical-align: middle; margin-right: 5px; } .todo-footer button { float: right; margin-top: 5px; } </style>
8.案列_清除所有已完成的
App.vue
// 清除已经已经勾选的 clearAllDoneFather(){ this.todos=this.todos.filter((value)=>{ // 假如说done值为false就不用过滤-保留,否则就需要过滤-不保留 return value.done===false }) }
<template> <div> <div class="todo-container"> <div class="todo-wrap"> <!-- 1.头部 将父APP.VUE的addFather方法传递给子组件--> <Header :addFatherA="addFather"/> <!-- 2.列表 : 将父APP.VUE的todos数组传递给子组件--> <list :todosA="todos" :updateFatherA="updateFather" :deleteFatherA="deleteFather" /> <!-- 3.底部导航 --> <Footer :FooterTodos="todos" :updateAllFatherA="updateAllFather" :clearAllDoneFatherA="clearAllDoneFather" /> </div> </div> </div> </template> <script> // 1.引入组件 import Header from './components/Header.vue' import List from './components/List.vue' import Footer from './components/Footer.vue' export default { name:'App', // 目的是在浏览器VUE插件中的名字都是App不会被改变。 // 2.注册组件 components:{ Header, List, Footer }, data() { return { todos:[ {id:'001',name:'抽烟',done:true}, {id:'002',name:'喝酒',done:false}, {id:'003',name:'烫头',done:true} ] } }, methods: { addFather(todoObj){ // 这个方法是对todos这个数组的尾部追加对象todoObj this.todos.unshift(todoObj) }, /* 利用id updateFather(id,doneA){ // 利用map遍历数组todos,获取到的分别是数组对象和对象坐标 this.todos=this.todos.map((value,index)=>{ if(id===value.id){ // 假如说子类传递过来的值和map遍历的值一样,那么就返回 所有的属性+修改后的值 return {...value,done:doneA} }else{ return value } }) } */ // 更新 updateFather(index,doneA){ this.todos[index].done=doneA }, // 删除 deleteFather(index){ // 根据坐标删除数据 this.todos.splice(index,1) }, // 全选或者不选 updateAllFather(doneOption){ // map():创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。 this.todos=this.todos.map((value)=>{ // 这个参数是遍历的单个对象 return {...value,done:doneOption} // 返回将done属性改编为doneOption的完整对象 }) }, // 清除已经已经勾选的 clearAllDoneFather(){ this.todos=this.todos.filter((value)=>{ // 假如说done值为false就不用过滤-保留,否则就需要过滤-不保留 return value.done===false }) } }, } </script> <style> /*base*/ body { background: #fff; } .btn { display: inline-block; padding: 4px 12px; margin-bottom: 0; font-size: 14px; line-height: 20px; text-align: center; vertical-align: middle; cursor: pointer; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); border-radius: 4px; } .btn-danger { color: #fff; background-color: #da4f49; border: 1px solid #bd362f; } .btn-danger:hover { color: #fff; background-color: #bd362f; } .btn:focus { outline: none; } .todo-container { width: 600px; margin: 0 auto; } .todo-container .todo-wrap { padding: 10px; border: 1px solid #ddd; border-radius: 5px; } </style>
Footer.vue
<template> <div> <div class="todo-footer"> <label> <!-- 类型为checkbox 的值是布尔值 --> <input type="checkbox" v-model="isAll"/> </label> <span> <span>已完成{{doneCount}}</span> / 全部{{total}} </span> <button class="btn btn-danger" @click="clearAllDone">清除已完成任务</button> </div> </div> </template> <script> export default { name:'Footer', // 声明 props:['FooterTodos','updateAllFatherA','clearAllDoneFatherA'], // 1.利用计算属性进行获取已完成 computed:{ // 被选择的 doneCount(){ // 数组的所有方法以及定时函数的所有方法都是归window管理的 // 数组.reduce(累加数据,初始值) js自带的累加器 return this.FooterTodos.reduce((pre,current)=>pre+=current.done ? 1: 0,0) // 匿名方法的参数:(上次调用函数的返回值,当前元素) }, // 总数 total(){ return this.FooterTodos.length; }, // 计算属性是顺序的,也就是可以套娃 isAll:{ // 全选的效果 set(flag){ //获取到的是一个布尔值 console.log(flag) // 通知父App.vue传递方法 return this.updateAllFatherA(flag) }, // get(){ return this.doneCount===this.total && this.total>0 } } }, methods: { clearAllDone(){ if(confirm('确定删除已经完成的任务么?')){ // 通知父组件安排方法 this.clearAllDoneFatherA(); } } }, } </script> <style scoped> /*footer*/ .todo-footer { height: 40px; line-height: 40px; padding-left: 6px; margin-top: 5px; } .todo-footer label { display: inline-block; margin-right: 20px; cursor: pointer; } .todo-footer label input { position: relative; top: -1px; vertical-align: middle; margin-right: 5px; } .todo-footer button { float: right; margin-top: 5px; } </style>
9.todoList 小结⭐⭐⭐⭐
(1).filter过滤数组的总结
array.filter(function(currentValue,index,arr), thisValue);
3、参数
返回值
4、用法
filter() 方法用于把Array中的某些元素过滤掉,然后返回剩下的未被过滤掉的元素。
5、注意事项
(1)filter() 不会对空数组进行检测;
(2)filter() 不会改变原始数组。
6、如果返回值为true就不过滤掉-保留、否则就过滤-不保留
- 简单实列
1.返回数组nums中所有大于5的元素
let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let res = nums.filter((num) => { return num > 5; }); console.log(res); // [6, 7, 8, 9, 10]
- 过滤数组对象中done值不为false的值、
arrA=arrB.filter((value)=>{ // 假如说done值为false就不用过滤-保留,否则就需要过滤-不保留 return value.done===false })
- 模糊查询
name.indexOf(keywords) 该方法将从头到尾地检索数组,看它是否含有对应的元素。如果在数组中没找到指定元素则返回 -1
。
filter的参数为一个的时候,return 和{}可以同时省略
fmtPersons(){ const {keywords} = this; //这里相当于 const keywords=this.keywords; return this.persons.filter(p=>p.name.indexOf(keywords)!==-1); }
fmtPersons(){ const {keywords} = this; //这里相当于 const keywords=this.keywords; return this.persons.filter((p)=>{ return p.name.indexOf(keywords)!==-1}); }
(2).map过滤数组的总结
- 遍历数组对象
里面的参数第一个遍历的对象与所在的坐标
返回值: {...value,done:doneOption} 就是除了将原有对象属性done改为doneOption之外其他都不变的对象
updateAllFather(doneOption){ // map():创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。 this.todos=this.todos.map((value)=>{ // 这个参数是遍历的单个对象 return {...value,done:doneOption} // 返回将done属性改编为doneOption的完整对象 }) },
(3).增、删、改
1. 根据坐标更改某一个对象的值 // 更新 updateFather(index,doneA){ arr[index].done=doneA }, 2.根据坐标删除某一个对象 // 删除 deleteFather(index){ // 根据坐标删除数据 arr.splice(index,1) }, 3.向某个数组的头部添加 addFather(todoObj){ // 这个方法是对todos这个数组的尾部追加对象todoObj arr.unshift(todoObj) },