写点什么

Vue 进阶(幺伍零):巧用 key 提升页面渲染性能及触发生命周期函数

发布于: 刚刚
Vue进阶(幺伍零):巧用 key 提升页面渲染性能及触发生命周期函数

一、前言

Vue.jsv-for更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。

二、key 的两种应用场景

2.1 在列表渲染时使用 key 属性

假设Vue实例的data属性中有一个叫numbers的变量,它的值是[1, 2, 3, 7, 8, 9]:


<div v-for="num in numbers">  {{num}}</div>
复制代码


这种情况下应当是渲染了 6 个<div>元素,其中的内容分别对应 numbers 中 6 个数字,此时如果 numbers 变成了[0, 1, 2, 3, 7, 8, 9],即在数组头部插入了一个数字 0,在没有 key 属性的情况下,渲染输出的更新步骤是这样的:


原先内容为 1 的<div>元素内容变成 0,原先内容为 2 的<div>元素内容变成 1,……以此类推,最后新增一个<div>元素,内容为 9。


在这种情况下,Vue会通过改变原来元素的内容和增加/减少元素来完成这个改变,因为没有key属性,Vue无法跟踪每个节点,只能通过这样的方法来完成变更。


让我们对以上代码进行一个小修改:


<div v-for="(num, index) in numbers" :key="index">  {{num}}</div>
复制代码


这里用index变量,根据列表渲染的规则,它实际上对应了数组中每个元素的索引,这样做的好处是它可以使得每个元素的key值都不同,这是很重要的,如果我们要利用key属性的优点,必须保证同一父元素的所有子元素有不同的key属性。


此时如果 numbers 从[1, 2, 3, 7, 8, 9]变成了[0, 1, 2, 3, 7, 8, 9],渲染输出的更新步骤就变化了:


新增一个<div>元素,它的内容为 0,并将它插入原先内容为 1 的元素之前。


在有了key属性之后,Vue会记住元素顺序,并根据这个顺序在适当位置插入/删除元素来完成更新,这种方法比没有key属性的就地复用策略效率更高。


总体来说,当使用列表渲染时,永远添加key属性,这样可以提高列表渲染的效率,提高页面性能。但是key取值不建议使用index,原因详参博文《Vue进阶(幺伍幺):Vue 应用key提升页面渲染性能》。

2.2 使用 key 属性强制替换元素

key属性还有另外一种使用方法,即强制替换元素,从而可以触发组件的生命周期钩子或者触发过渡。因为当key改变时,Vue认为一个新的元素产生了,从而会新插入一个元素来替换掉原有的元素。


借用官方文档上的例子:


<transition>  <span :key="text">{{text}}</span></transition>
复制代码


这里如果 text 发生改变,整个<span>元素会发生更新,因为当 text 改变时,这个元素的key属性就发生了改变,在渲染更新时,Vue会认为这里新产生了一个元素,而老的元素由于key不存在了,所以会被删除,从而触发了过渡。


假如没有key属性:


<transition>  <span>{{text}}</span></transition>
复制代码


那么当 text 改变时,Vue会复用元素,只改变<span>元素的内容,而不会有新的元素被添加进来,也不会有旧的元素被删除。


同理,key属性被用在组件上时,当key改变时会引起新组件的创建和原有组件的删除,此时组件的生命周期钩子就会被触发。

三、拓展阅读

发布于: 刚刚阅读数: 3
用户头像

No Silver Bullet 2021.07.09 加入

岂曰无衣 与子同袍

评论

发布
暂无评论
Vue进阶(幺伍零):巧用 key 提升页面渲染性能及触发生命周期函数