key的原理
-
虚拟DOM中的key的作用:
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据新数据生成新的虚拟DOM,
随后Vue进行新的虚拟DOM与旧的虚拟DOM的差异比较,比较规则如下
-
对比规则:(diff算法)
(1). 旧虚拟DOM中找到了与新的虚拟DOM相同的key:
若虚拟DOM中的内容没变,直接使用之前的真实DOM
若虚拟DOM中的内容变了,则生成新的真实DOM,随后替换掉页面中的真实DOM
(2).旧虚拟DOM中未找到与新的虚拟DOM相同的key:
创建新的虚拟DOM,随后渲染到页面
-
用index作为key可能会引发的问题:
(1).若对数据进行:逆序添加、逆序删除等破坏顺序操作:
会产生没有必要的真实DOM更新(界面效果没有问题,但效率低)
(2).如果结构中还包含输入类的DOM:
会产生错误的DOM更新(界面有问题)
-
开发中如何选择key?
(1).最好使用每条数据的唯一标识作为key,比如id、手机号、身份证等
(2).如果不存在数据的逆序添加、逆序删除等破坏顺序的操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。
列表过滤
两种实现方法
-
watch实现
watch:{ keyWord:{ immediate:true, handler(val){ this.filPersons = this.persons.filter((p)=>{ return p.name.indexOf(val) !== -1 }) } } }
-
computed实现
computed:{ filPersons(){ return this.filPersons = this.persons.filter((p)=>{ return p.name.indexOf(this.keyWord) !== -1 }) } }
当watch与computed可以同时实现时,一般采用computed,因为computed是计算出来的属性,所以不需要immediate也不需要再创建一个空的filPersons
列表排序
<body> <div id="root"> <h2>人员列表</h2> <input type="text" placeholder="请输入名字" v-model="keyWord"> <ul> <li v-for="p in filPersons" :key="p.id">{{p.name}}--{{p.age}}--{{p.sex}}</li> </ul> <button @click="sortType=2">升序排序</button> <button @click="sortType=1">降序排序</button> <button @click="sortType=0">原顺序</button> </div> <script> new Vue({ el:'#root', data:{ keyWord:'', sortType:0,//0原顺序、1降序、2升序 persons:[ {id:'001',name:'马冬梅',age:'18',sex:'女'}, {id:'002',name:'周冬雨',age:'19',sex:'女'}, {id:'003',name:'周杰伦',age:'20',sex:'男'}, {id:'004',name:'温兆伦',age:'21',sex:'男'}, ], }, computed:{ filPersons(){ const arr = this.filPersons = this.persons.filter((p)=>{ return p.name.indexOf(this.keyWord) !== -1 }) //判断一下是否需要排序 if(this.sortType){ arr.sort((p1,p2)=>{ return this.sortType === 1 ? p2.age-p1.age : p1.age-p2.age }) } return arr } } }) </script> </body>