无论开发小程序还是 Vue 应用,都经常会使用到列表渲染,在使用过程中,如果不绑定 key
值,ide 经常警告需要绑定 key
值。但是一直都没有去深究为什么需要绑定一个 key
值,现在终于有时间了,所以去关注一下这些底层的东西。
举个栗子
<head>
<title>v-key</title>
</head>
<body>
<div id="app">
<div>
<input type="text" v-model="username">
<button @click="addUser">添加用户</button>
</div>
<div v-for="user in users"> //:key="user.id"
<input type="checkbox">{{user.username}}
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script>
var app = new Vue({
el: '#app',
data: {
curId: 3,
username: '',
users: [
{
id: 1,
username: '小红'
},
{
id: 2,
username: '小明'
},
{
id: 3,
username: '小天'
}
]
},
methods: {
addUser() {
this.users.unshift({
id: ++this.curId,
username: this.username
});
this.username = '';
}
}
});
</script>
不绑定 key
的情况,从数组头部添加元素时,checkbox 选中的永远是第二条数据。
当将 key
绑定为 user 的 id 时,checkbox 选中的元素即可不受新增元素影响。
怎么如此?🤔
这就要从 Vue 的 diff 算法说起了,算了,不扯这么远(菜狗
先上图,下面是没有 key
和有 key
的比较过程。
这是未绑定 key
时的比较过程:
这是绑定 key
时的比较过程:
通过上面两幅图可以看出,当绑定 key
之后,节点更新时,节点的比较只会和 key
相同的节点进行对比,从而节省的 DOM 操作的开销,除了避免例子里面的情况,同时还会提高渲染效率。
然后绑定 key 时建议是选择静态不变的唯一值,不要绑定数组的索引,我以前就是一知半解,一直绑定的是数组的索引...
最后,算是把这个 key
值给搞明白了!