一文详解Vue中加上key后发生什么
作者:舟羽
前言
最近接手了一个Vue项目,很多的代码片段使用到了key, 结合自己以前接触key的经历,于是思考,在Vue中加上key发生了什么? 最后翻找资料,写下这篇博客记录。
什么是Key
在Vue中,我们通常会使用v-for
指令来渲染列表。 当数据源发生改变时,Vue会尽可能高效地更新DOM元素以反映这些变化。 然而,在某些情况下,Vue无法跟踪并处理到底哪些元素发生了变化。
当一个Vue组件的状态发生改变时,Vue会重新渲染组件反应出这些变化。 但是,如果这个Vue组件中包含列表,那么每次重新渲染时,都要重新创建这个列表。 当这个列表发生以下操作时,都会重新更新整个列表。 如果这个列表的数据量很大的时候,这样操作会极大影响性能。
- 新增或删除列表项
- 对比列表项发现位置已经变动
- 通过第三方插件对列表进行操作
为了解决上述问题,Vue引入了一种特殊属性——key
。
Key是用来追踪哪些元素被新增、被修改、被删除的辅助标识。在进行前后对比时, 会基于Key的变化判断是复用现有DOM节点还是销毁再重建,从而提高Vue的渲染效率和性能。
在Vue的虚拟DOM算法中,同级别的元素之间互相比较是按照它们的先后顺序进行遍历的。 如果可复用的元素没有设置Key,则会按照就近原则,配对成功后更新差异,这可能导致内部状态混乱。
key的作用
key属性用于标识一个元素的唯一性,当列表中的数据发生改变时,Vue会根据key值来对比哪些数据是新的,哪些数据是旧的, 从而渲染新的数据,而不用渲染整个列表。
- Key可以告诉Vue哪些元素是新增的,哪些元素已经不存在了,进而更好地掌握整个组件内部的状态。
- 通过给每个元素添加key,Vue可以更加精确地知道哪些元素被修改了,减少内部状态混乱和无谓的DOM操作,从而提高性能。
举个🌰
<template> <ul> <li v-for="item in items" :key="item.id"> {{ item.name }} </li> </ul> </template> <script> export default { data() { return { items: [ { id: 1, name: 'Apple' }, { id: 2, name: 'Banana' }, { id: 3, name: 'Orange' } ] }; }, mounted() { setInterval(() => { this.items.push({ id: Date.now(), name: 'New Item' }); }, 1000); } }; </script>
在这个例子中,我们使用v-for
指令来渲染一个列表,并为每个列表项设置了一个key属性。 同时使用setInterval函数来定时添加新的列表项。
如果我们不使用key属性,那么每次添加新的列表项时,Vue都会重新渲染整个列表。 这样会导致性能问题,并且会破坏一些用户交互效果。 但是,如果我们使用key属性,Vue就可以根据每个列表项的唯一标识来判断哪些是新的,哪些是旧的。 这样就可以只更新需要更新的元素,而不是重新渲染整个列表。
key的底层原理
我们先来了解Vue中实现key的底层原理步骤:
- 创建一份当前的虚拟DOM和上一次的虚拟DOM;
- 在数据发生改变后,vue会通过比较新旧虚拟DOM的差异来计算出需要对哪些DOM元素进行何种类型的操作(新增、删除、移动等);
- 如果某个元素上添加了key属性,在计算差异时vue就会将其作为参考,如果两次数据更新时,某个元素的key值没有发生变化,则代表这个元素没有发生位置变化,vue会直接复用它,而不是重新渲染。
修改上面的🌰
<template> <button @click="add">Add Fruit</button> <ul> <li v-for="item in items" :key="item.id"> {{ item.name }} </li> </ul> </template> <script> data() { return { items: [ { id: 1, name: 'Apple' }, { id: 2, name: 'Banana' }, { id: 3, name: 'Orange' } ] }; }, methods:{ add(){ const fruit = {'id':'4', 'name':'Chestnut'} this.items.unshift(fruit) } } </script>
当vue第一次渲染时,会根据items
中的数据加载生成虚拟DOM,同时绑定key值,最后加载为以下的真实DOM节点。
<li key="1">Apple</li> <li key="2">Banana</li> <li key="3">Orange</li>
当我们点击 button
按钮后,items
数据源发生变化,此时vue仍进行渲染,再次生成虚拟DOM,不过会对比上一次生成的虚拟DOM,最后根据绑定的key值重新渲染,加载为以下的真实DOM节点。
<li key="1">Apple</li> <li key="2">Banana</li> <li key="3">Orange</li> <li key="4">Chestnut</li>
到此这篇关于一文详解Vue中加上key后发生什么的文章就介绍到这了,更多相关Vue key 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!