大家要知道,不仅只是vue中,react中在执行列表渲染时也会要求给每个组件添加key这个属性
如果想知道key的作用,不得我们得聊一下虚拟DOM的Diff算法
所谓虚拟DOM的诞生,使我们可以不直接操作DOM元素,只操作数据便可以重新渲染页面。而隐藏在背后的原理便是其高效的Diff算法,它的核心是基于两个简单的假设:
-
两个相同的组件产生类似的DOM结构,不同的组件产生不同的DOM结构
-
同一个层级的一组节点,他们可以通过唯一的id进行区分
当页面的数据发生变化时,Diff算法只会比较同一层级的节点:
如果节点类型不同,直接干掉前面的节点,再创建并插入新的节点,不会再比较这个节点以后的子节点了
如果节点类型相同,则会重新设置该节点的属性,从而实现节点的更新
当某一层有很多相同的界定啊时,也就是列表节点,Diff算法的更新过程默认情况下也是遵循以上原则
既把C更新成F,D更新成C,E更新成D,最后再插入E,是不是很没有效率?
所有我们需要使用key来给每个节点做一个唯一的标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点
所以一句话,key的作用主要是为了高效的更新虚拟DOM。另外vue的在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分他们,否则vue只会替换其内部属性而不会触发过渡效果。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
.userList{
border: 1px solid red;
margin: 20px 0;
padding: 10px 10px;
}
</style>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="vue.js"></script>
<script src="lodash.min.js"></script>
<script type="text/javascript">
Vue.component('my-com',{
template:`
<div class = 'userList'>
<div class = 'content'>
<h3>{{obj.name}}</h3>
<p>{{obj.content}}</p>
</div>
<div class ='control'>
<input type="text" placeholder = '请输入你的名字' />
</div>
</div>
`,
props:{
obj:Object
}
})
var App = {
data(){
return {
datas:[
{id:1,name:'张三',content:'我是张三'},
{id:2,name:'李四',content:'我是李四'},
{id:3,name:'王五',content:'我是王五'}
]
}
},
template:`
<div>
<button @click = 'change'>改变顺序</button>
<my-com v-for = '(item,index) in datas' :obj = 'item' :key = 'item.id'></my-com>
</div>
`,
methods:{
change(){
console.log(1);
this.datas = _.shuffle(this.datas);
}
}
};
new Vue({
el:'#app',
components:{
App
},
template:`<App />`
});
</script>
</body>
</html>
网友评论