面试题:vue/react/小程序中的key的作用是什么?是否建议使用index下标进行key的设置?能够使用下标进行key的设置呢?为什么?

本文介绍Vue、React及微信小程序中key属性的作用与原理,通过合理使用key,可以显著提升列表渲染性能,保持组件状态,避免不必要的DOM操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

key的最大作用是为了更加高效的更新虚拟dom 提升性能

Vue中key属性的作用 :

在vue中使用相同标签元素的过度切换的时候,也需要使用key属性,其目的是为了让vue区分它们
在列表渲染时使用key属性
v-for
1 .当使用v-for更新已经渲染过的元素列表时,默认的使用”旧地复用“策略,如果数据项的顺序被改变,Vue是不会移动dom来匹配数据项的顺序,而是简单的复用此处的每个元素,并且确保他在特定索引下显示已被渲染过的元素
2 .这个模式默认是高效的,但是只适用于不依赖子组件状态或临时DOM钻港台,比如列表渲染输出
3 .为了给Vue一个提示,使他可以追踪每个节点的身份,从而重用和重新排序现有元素,这就需要为每一个项提供一个唯一的key属性
4 .注意:不添加key的性能其实更加优秀。除了想要性能或者输出非常的内容非常简单
5 .不要使用对象或者数组之类的非原始值作为v-for的key,用字符串或者整数类型的值来取代
6.总体来说,当使用列表渲染时,永远添加key属性,这样可以提高列表渲染的效率,提高了页面的性能。
v-if
1 .v-if中想要渲染多个元素的时候,可以把一个template元素当成不可见的包裹元素,并在上面使用v-if,最终的渲染结果将不会包括template元素
2 .为了尽可能高效的渲染元素,通常会复用已有元素而不是从头开始渲染,除了更快,还以一些其他的好处
.以下是没有key的时候
.input切换的时候,会保留之前填的表格
3 .添加一个key值,vue就知道这两个元素是完全不一样的,所以创建的时候直接从0开始,而不是复用
4 .但是如果其他的地方没加key,也是会复用的。所以要在合适的位置加上key
5 .v-show:带有v-show的元素始终会被渲染并保留在dom中,v-show只是简单的切换css属性display
6 .不支持template,也不支持v-else

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

{{text}}

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

假如没有key属性:

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

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

react中的key的作用

如果为父节点添加多个相同的子节点时,不添加key属性,会报错但同时也会渲染出dom,渲染出dom其实是证明能从差异对象中渲染出真实dom,但报错的原因是因为这种写法会影响渲染的性能,不利于生成dom节点。

作用:
当我们生成两个不同的数组时,我们可以使用相同的 key 值:
key的作用主要是用来减少没必要的diff算法对比,因为对于一个组件或者节点来说,只要父节点状态或者属性发生变化,该组件就会进行diff对比,即使该组件没变化,而如果为组件引入了key值,就可以在diff对比前先做一个校验,判断该组件是否需要diff对比,即使是diff对比,也可以判断该组件是直接更新操作还是销毁或者新建操作,从而提高了diff算法的效率;

特别在渲染同级同结构的组件们时,key可以为它们加上了身份的标志,在rerender时,可以通过key来判断该组件是否已经存在,是否需要跟新或者销毁,新建等操作,提高了diff算法在同级节点上的操作。

原理:

因为在reactelement中有一个属性是key,该属性默认是为空值,所以一般情况下,只要组件不加上key值,react是不会去校验组件的key,而是直接采用diff算法进行对比,一旦组件加上了key值,react就会在渲染时对该组件的身份进行校验,首先校验新旧组件的key值是不是一致,不一致的话,该组件直接销毁,然后在新建该组件;如果一致,则比较组件的属性是否发生变化,如果发生变化,则采用diff算法进行对比,然后得出差异对象,如果属性没发生变化,则认为该组件不需要改变;

key相同:若组件属性有所变化,则react只更新组件对应的属性;没有变化则不更新。
key值不同:则react先销毁该组件,然后重新创建该组件。
用法:

(一般同级同结构的子节点都需要采用key属性,方便diff算法的使用)

纯静态的同级同结构节点的渲染,可以采用index作为key的值,因为这里不需要动态去变化节点里面的内容的值;
对于一组动态变化的数组来说,采用index作为key的值,会有可能出现问题,因为index的值和数组内的元素内容不具有关联性,所以即使采用了index作为key,子组件的内容有可能不会随着属性的变化而发生变化(只要组件内该元素不与属性构成联系),所以一般采用数组中元素的某一个唯一值作为key,这样一来,只要统一位置的节点的key值不一致,就会直接销毁和新建而不是直接更新;
对于一个不想受到父组件属性状态影响而导致没必要的渲染的组件,可以采用key值,因为只要key值不发生改变,组件的属性不变,即使父组件渲染,该组件也不会发生变化,只有组件的状态或者属性发生变化,组件才会二次渲染;一旦key值变化,就直接组件销毁然后再新建该组件。

微信小程序key的作用 :

wx:key
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 中的输入内容, 的选中状态),需要使用 wx:key 来指定列表中项目的唯一的标识符。
wx:key 的值以两种形式提供
字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字,如:

当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组

件保持自身的状态,并且提高列表渲染时的效率。

是否建议使用index下标进行key的设置?能够使用下标进行key的设置呢?为什么?
一般不太建议使用index代替key
vue: 1 .index值不是一定不变的,如果不加key值的话,删除前面的项。后面的index可能变也可能不变,比如加个定时器的时候会变,不加定时器不会变
2 .不加key的话,更新机制的进行diff的时候是会全部比较的,比如删除第一个的话,后面的元素其实都不一样,会一项一项的比较。然后全部元素都替换,没有做到最小更新。而且里面的传的值也会变,如果这个时候你要根据里面的值删除元素的话,就会出错,尤其是加了定时器之后
3 .所以这个key值对数据改变之后的diff更新比较有很大的性能提升,或者说有了key和没有key是两种比较和更新机制 4.如果有key的话,就会根据key值去判断某个是否修改,重新渲染这一项…

react: 当数组中的数据发生变化时: React 比较更新前后的元素 key 值,如果相同则更新,如果不同则销毁之前的,重新创建一个元素。当以数组的下标index作为key值时,其中一个元素发生了变化 就有可能导致所有元素的key值发生改变 。所以,index作为key值和没加index是一样的,并不能提升性能。

微信小程序:

默认情况下item -index的名字是固定的 但是在一些情况我们可能想使用其他的名字 或出现多层遍历 名字会重复
这个时候可以指定item index的名称
其实现在小程序内部也使用了虚拟DOM的关系(和vue react很相似) 如果这个时候我们想插入一个新的列表节点 Diff算法会默认执行起来
如果有key的话,为每一个元素绑定一个id,先判断key绑定的id有没有变化,如果没有变化的话,就进行复用,接着将新创建的key插入到正确的位置。key是唯一标识
总的说 key属性可以提高性能 !!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值