• Vue在渲染列表的时候,为什么不建议用数组的下标当做列表的key


    结论先行

    1、Vue 中 key 值的作用存在两种情况:

    ① 在 v-if 中使用 key

    例如给 input 输入框添加 key 值,来标识这个输入框的唯一性,避免错误复用。

    ② 在 v-for 中使用 key

    是为了给每个虚拟 DOM 添加一个唯一的标识符。

    因为 Vue 的更新机制是基于 diff 算法实现的,底层会通过 key 值快速比对判断是否是相同节点,以便高效地更新 DOM。

    如果不添加 key,diff 算法只能通过遍历子节点的方式查找,效率较低。

    2、为什么不建议用数组的下标当做列表的 key?

    因为要保证渲染列表的性能和正确性。因为 Vue 的更新机制是基于 diff 算法实现的,底层会通过 key 值快速比对判断是否是相同节点,以便高效地更新 DOM。

    那如果将数组下标作为 key 值的话,可能存在 key 值紊乱从而引发不必要的组件重新渲染,就会导致性能的下降。

    例如,当删除列表中某个元素时,其后面的所有元素的下标都会发生改变,导致后面的每个项都会被重新渲染。这会造成性能下降,尤其是在大型列表中。

    使用 index 作为 key 和没写基本上没区别,因为不管数组的顺序怎么颠倒,index 都是 0, 1, 2...这样排列,导致 Vue 会复用错误的旧子节点,做很多额外的工作。

    那为了避免这个问题,我们一般使用数据库记录的 id 字段或其他全局唯一的标识符作为 key 值。这样在列表发生变化的时候,能够正确地更新和复用 DOM 元素,提高性能。

    具体解析:

    1、 在 Vue 中,key 的作用

    Vue 中 key 值的作用可以分为两种情况来考虑:

    ① 在 v-if 中使用 key

    由于 Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。

    因此当使用 v-if 来实现元素切换的时候,如果切换前后含有相同类型的元素,那么这个元素就会被复用。如果是相同的 input 元素,那么切换前后用户的输入不会被清除掉,这样是不符合需求的。

    此时,我们就可以使用 key,给每一个 input 框添加一个唯一的标识 key,来标识元素的唯一性。

    这个情况下,使用 key 的元素不会被复用这个时候 key 的作用是用来标识一个独立的元素。

    1. <div>
    2. <button @click="toggle">切换表单button>
    3. <template v-if="showUserName">
    4. <label>用户名label>
    5. <input placeholder="输入用户名" key="username-input">
    6. template>
    7. <template v-else>
    8. <label>昵称label>
    9. <input placeholder="输入昵称" key="nickname-input">
    10. template>
    11. div>

    在没有加 key 之前,在切换表单时,用户名中的 input 框未清空。原因是 DOM 的复用。

    所以,为每一个 input 框增加一个 key 值,不同 key 值的 input 框就不会复用了。

     

    ② 在 v-for 中使用 key

    用 v-for 更新已渲染过的元素列表时,它默认使用“就地复用”的策略。如果数据项的顺序发生了改变,Vue 不会移动 DOM 元素来匹配数据项的顺序,而是简单复用此处的每个元素。

    因此通过为每个列表项提供一个 key 值,来以便 Vue 跟踪元素的身份,从而高效的实现复用。这个时候 key 的作用是为了高效的更新渲染虚拟 DOM。

    key 是为 Vue 中 vnode 的唯一标记,通过这个 key,diff 操作可以更准确、更快速。

    • 更准确:因为带 key 就不是就地复用了,在 sameNode 函数 a.key === b.key 对比中可以避免就地复用的情况。所以会更加准确。
    • 更快速:利用 key 的唯一性生成 map 对象来获取对应节点,比遍历方式更快

    在 diff 算法的过程中,key 的作用是给每个虚拟DOM节点添加一个唯一的标识符。

    这样在进行新旧虚拟 DOM 对比时,可以通过 key 值的对比快速判断是否是同一个节点,避免不必要的 DOM 操作。

    如果不添加 key,diff 算法只能通过遍历子节点的方式查找,效率较低。(如果没有使用 key,Vue 会尝试通过就地复用和移动算法来尽可能减少DOM 操作,但这可能会导致一些意外的行为,例如,数据不一致、输入框内容丢失等  )

     

    2、在渲染列表的时候,为什么不建议用数组的下标当做列表的 key?

    在 Vue 渲染列表时,需要为每一项提供一个唯一的 key 属性。主要是用于帮助 Vue 跟踪每个列表项的身份,以便在列表发生变化时可以高效地更新 DOM。

    如果使用数组的下标作为 key 值,虽然可以满足每个元素 key 值唯一的需求但是由于 Vue 的更新机制是基于 diff 算法实现的,使用数组下标作为 key 值会导致 Vue 无法正确地判断列表中元素的变化情况。 

    具体来说,如果将数组下标作为 key 值,那么当列表发生变化时,可能会导致 key 值发生改变,从而引发不必要的组件重新渲染。

    例如,当删除列表中某个元素时,其后面的所有元素的下标都会发生改变,导致后面的每个项都会被重新渲染。这会造成性能下降,尤其是在大型列表中。

    那为了避免这个问题,我们一般使用数据库记录的 id 字段或其他全局唯一的标识符作为 key 值。这样在列表发生变化的时候,能够正确地更新和复用 DOM 元素,提高性能。

    为了避免这个问题,我们需要为每一项提供一个稳定的、与其内容相关的唯一 key 值,例如使用元素的 id 属性作为 key 值。这样可以确保每个项都有独一无二的 key,并且在列表变化时能够正确地更新和复用 DOM 元素,提高性能。

  • 相关阅读:
    服务端Skynet(四)——lua层消息处理机制
    OpenMV输出PWM,实现对舵机控制
    Cut-Off Wavelength in fiber(光纤的截止波长)
    BAT大厂Java面试,如何抓住面试重点知识?收割大厂offer
    「三」配置语法、配置文件高亮
    零基础学Java(7)大数
    音乐制作软件 Ableton Live 11 Suite mac中文版功能介绍
    C#实现在企业微信内创建微信群发送群消息
    一个 MySQL 隐式转换的坑,差点把服务器整崩溃了
    gitbook在centos上安装
  • 原文地址:https://blog.csdn.net/qq_38290251/article/details/133655786