react、Vue中的key有什么作用?(key的内部原理)

lxf2023-05-05 18:14:01

持续创作,加速成长!这是我参与「AdminJS · 6 月更文挑战」的第3天,点击查看活动详情 今天我们补充一下列表渲染v-for的基本概念和分析key的原理和规则

列表渲染

v-for指令

  1. 用于展示列表数据
  2. 语法:v-for=“(item,index)in xxx” :key="yyy"
  3. 可遍历:数组、对象字符串(用的很少)、指定次数(用的很少)

例子

//遍历数组
<li v-for="(p,index) of persons" :key="index">
     {{p.name}}-{{p.age}}
    </li>

//遍历对象
<li v-for="(value,k) of car" :key="k">
     {{value}}-{{k}}
    </li>

//遍历字符串
<li v-for="(char,index) of str" :key="index">
     {{char}}-{{index}}
    </li>

//遍历指定次数
<li v-for="(number,index) of 5" :key="index">
     {{index}}-{{number}}
    </li>

react、Vue中的key有什么作用?(key的内部原理)

  1. 虚拟DOM中key的作用 key是虚拟DOM对象的表示,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较

  2. 对比规则: (1)旧虚拟DOM中找到了与新虚拟DOM相同的key:

    ​ ①若细腻DOM中内容没变,直接使用之前的真是DOM;

    ​ ②若虚拟DOM中内容改变,则生成新的真是DOM,随后替换掉页面中之前的真实DOM

    ​ (2)旧虚拟DOM中未找到与新虚拟DOM相同的key

    ​ 创建新的真实DOM,随后渲染到页面

  3. 用index作为key可能会引发的问题: (1)若对数据进行:逆序添加、逆序删除等破坏顺序操作:

    ​ 会产生没有必要的真实DOM更新 ==> 界面效果没问题,但是效率低

    ​ (2)如果结构中还包含输入类的DOM:

    ​ 会产生错误DOM更新 == > 界面有问题

  4. 开发中如何选择key

    1. 最好使用每条数据的唯一表示作为key,比如id、手机号、身份证号、学号等唯一值。
    2. 如果不存在对数据的逆序添加、逆序删除等破环顺序操作,仅用于渲染列表用于展示,使用index作为key时没有问题的

小结

​ vue和react都是采用diff算法来对比新旧虚拟节点,从而更新节点。在交叉对比中,当新节点跟旧节点头尾交叉对比没有结果时,会根据新节点的key去对比旧节点数组中的key,从而找到相应的旧节点(这里对应的是一个key=>index的map映射)。

​ 如果没有找到就认为是一个新增节点。而如果没有key,那么就会采用遍历查找的方式去找到对应的旧节点,一种一个map映射,另一种是遍历查找。

​ 相比而言,map映射速度更快。这种模式会带来一些隐藏的副作用,比如可能不会产生过度效果,或者在某些节点有绑定数据(表单)状态,会出现状态错位。

​ vue文档也说明了这个模式是高效的,但是只是适用于不依赖子组件状态或临时dom状态(例如:表单输入值)的列表渲染输出