列表过滤
-
<body> <div id="root"> <!--输入框用于模糊查询--> <input type="text" placeholder="请你输入名字" v-model="name"> <ul> <!--in可以换成of--> <li v-for="(p,index) in persons" :key="index">{{p.name}}-{{p.age}}-{{p.sex}}</li> </ul> </div> </body> <script> const vm = new Vue({ el:'#root', data: { name: '', persons:[ {id:'001',name:'马冬梅',age:'21',sex:'男'}, {id:'002',name:'周冬雨',age:'20',sex:'男'}, {id:'003',name:'蔡徐坤',age:'25',sex:'女'}, {id:'004',name:'周杰伦',age:'24',sex:'女'}, ], }, //只是监听的作用。先用简写看能不能解决问题 watch: { //参数有两个,一个为变化前的参数,一个为变化后的参数。这里只要变化后的参数 name(val){ //filter为过滤的作用,让其过滤出来.但过滤出来的是新数组没有改变原来的值。故用persons接收 this.persons = this.persons.filter((p)=>{ //p.name.indexOf(val)意思是让p.name中查询有没有与val值(也就是name属性)一样的,进行返回除-1以外的索引 return p.name.indexOf(val) !== -1 }) } } }) </script>
-
运行一下,因为过滤的缘故,越是搜索数据越少。预期不符.
解决方案:
1、加入空的数组 flashPersons,作用是保留persons数组的数据
2、用完整的watch加入 immediate: true进行尝试
3、用index方法将flashPersons显示出来数据,
-
<body> <div id="root"> <!--输入框用于模糊查询--> <input type="text" placeholder="请你输入名字" v-model="name"> <ul> <!--保留原来的数组--> <li v-for="(p,index) in flashPersons" :key="index">{{p.name}}-{{p.age}}-{{p.sex}}</li> </ul> </div> </body> <script> const vm = new Vue({ el:'#root', data: { name: '', persons:[ {id:'001',name:'马冬梅',age:'21',sex:'男'}, {id:'002',name:'周冬雨',age:'20',sex:'男'}, {id:'003',name:'蔡徐坤',age:'25',sex:'女'}, {id:'004',name:'周杰伦',age:'24',sex:'女'}, ], flashPersons: [], }, //因为要使用immediate:true,故不能缩写 watch: { name: { //加入immediate:true,当用户什么都没有输入时,p为空值。直接调用handler方法,p.name.indexOf(val)中p数组中每个对象的name空值为0,故符合查询条件,都显示出来。 immediate: true, handler(val){ this.flashpersons = this.persons.filter((p)=>{ return p.name.indexOf(val) !== -1 }) } } } } }) </script>
由于watch的复杂性,用computed计算属性更好
-
为什么计算属性更好,可以这么想。
-
1、computed是由data中的数据是计算得来的,无需像watch监听数据的改变才变化。
-
2、computed计算出来的属性,不会修改原来的属性。无需在创建空数组
-
<body> <div id="root"> <!--输入框用于模糊查询--> <input type="text" placeholder="请你输入名字" v-model="name"> <ul> <!--保留原来的数组--> <li v-for="(p,index) in flashPersons" :key="index">{{p.name}}-{{p.age}}-{{p.sex}}</li> </ul> </div> </body> <script> const vm = new Vue({ el:'#root', data: { name: '', persons:[ {id:'001',name:'马冬梅',age:'21',sex:'男'}, {id:'002',name:'周冬雨',age:'20',sex:'男'}, {id:'003',name:'蔡徐坤',age:'25',sex:'女'}, {id:'004',name:'周杰伦',age:'24',sex:'女'}, ], }, computed: { //计算属性没有用到修改set,直接用简写形式。 fashPersons(){ //filter方法返回的是新数组。计算属性的值由return返回 return this.persons.filter((p)=>{ return p.name.indexOf(this.name) !== -1 }) } } }) </script>
-
当注释后的代码,无法折叠时。可以用#region和#endregion
列表排序
-
思路分析
当点击升序,sortType的值变为2,之后执行v-for语句中flashPersons在查询的基础上。添加一个排序的方法。
点击原数组按钮,sortType的值变为0。回到只有查询的功能。也就是列表过滤的内容
-
<body> <div id="root"> <input type="text" placeholder="请你输入名字" v-model="name"> <button @click="sortType = 2">升序</button> <button @click="sortType = 1">降序</button> <button @click="sortType = 0">原数组</button> <ul> <!--保留原来的数组--> <li v-for="(p,index) in flashPersons" :key="index">{{p.name}}-{{p.age}}-{{p.sex}}</li> </ul> </div> </body> <script> const vm = new Vue({ el:'#root', data: { name: '', sortType: 0, persons:[ {id:'001',name:'马冬梅',age:'21',sex:'男'}, {id:'002',name:'周冬雨',age:'20',sex:'男'}, {id:'003',name:'蔡徐坤',age:'25',sex:'女'}, {id:'004',name:'周杰伦',age:'24',sex:'女'}, ], }, computed: { flashPersons () { //实现查询之后,这里将第一个return 改成 const num ,因为不着急进行返回数据。实现的功能是查询和排序一同实现 const num = this.persons.filter((p) => { //这个return 将数据返回给num return p.name.indexOf(this.name) !== -1 }) //this.sorType为true,也就是等于1或2 if (this.sortType) { //利用sort()方法实现升序和降序的功能,p1 - p2 为升序,p2 - p1为降序 num.sort((p1, p2) => { return this.sortType === 1 ? p2.age - p1.age : p1.age - p2.age }) } //这个return 将数据返回给flashPersons return num } } }) </script>
-
-