文章目录
1.在vue中使用v-for,未添加key时可能会出现的问题
示例
- html:
<div id="app">
<!-- 1.v-for不加key -->
<!-- 遍历输出书籍 -->
<div class="book" v-for="(item,index) in mybooks">
<input type="checkbox">我有哪些书:{{item.name}}
</div>
<!-- 点击添加书籍 -->
<div>
<input type="text" v-model="name" placeholder="添加书籍">
<button @dblclick="add">点击添加</button>
</div>
</div>
</div>
- script:
new Vue({
el:"#app",
data:{
mybooks:[
{id:1,name:"呐喊"},
{id:2,name:"活着"},
{id:3,name:"飘"}
],
id:3,
name:""
},
methods:{
add(){
this.mybooks.unshift({id:++this.id,name:this.name});//把新元素添加进入数组开头
this.name="";//清空input框
}
}
});
- 效果:
添加前:选择一个复选框
添加后:选择的复选框变成了另一本书
出现的原因
v-for中没有key时,会默认使用"就地复用"的策略,当数据项的顺序被改变,vue不是移动DOM元素来匹配新位置,而是简单复用原先位置的每个元素,这就会导致上面示例的情况
可以理解为:
没有key属性,状态默认绑定的是位置,有key时,状态根据key值绑定到相应的数组元素上
2.v-for加上key,并以item作为唯一key值
代码
- html
<!-- 2.v-for加上key -->
<div>
<!-- 加了唯一性的key后,id的checkbox跟内容进行了一个关联-->
<div class="book" v-for="(item,index) in mybooks" :key="item.id">
<input type="checkbox">我有哪些书:{{item.name}}
</div>
<div>
<input type="text" v-model="name" placeholder="添加书籍">
<button @dblclick="add">点击添加</button>
</div>
- 效果
添加前
添加后
发现复选框对应的书籍没有发生改变,取得我们想要的效果
v-for为什么要加上key?
v-for中添加key可以让每个循环出来的DOM添加唯一标识,从而高效地更新虚拟DOM,
可以快速找到节点,减少渲染次数,提高渲染性能
它的底层原理是这样的:
1.不加key的时候,每次操作DOM都会重新销毁和生成新DOM,这样会使性能消耗极大,
2.而加的key如果不是唯一标识(比如使用的是index而不是item),
则会导致内部复用错误的组件和DOM
3.添加正确的key后,由于vue的源码是内部数据驱动,通过改变数据来改变视图,
加上key之后,更容易定位到相应的元素,避免遍历DOM造成的性能消耗
注意事项
- key的取值必须是number 或 string,不能是对象,而且使用 v-for 循环的每一项的值,都要保证唯一性
- 理论上,不操作dom的时候就可以用index做key,或者不添加key,但是处于代码规范,开发者应自觉使用唯一标识作为key值
3.v-for的key值使用数组的索引index会造成什么影响?
原因
一旦删除或添加一个数据,这个数据之后的所有数据下标值都会被改变,
导致以前的数据和重新渲染后的数据随着 key 值的变化没法建立关联关系.
这就失去了 key 值存在的意义
例子
场景:使用v-for把一个数组渲染到页面上,使用数组下标作为key值
需求:点击一个复选框选中它,然后删除它
结果:被选中的元素虽然删除了,但他后面的元素的复选框被自动选中了