记得点击蓝字关注我们哦!经典面试题1.写 React / Vue 项目时为什么要在列表组件中写 key,其作用是什么?

vue和react都是采用diff算法来对比新旧虚拟节点,从而更新节点。在vue的diff函数中(建议先了解一下diff算法过程)。在交叉对比中,当新节点跟旧节点头尾交叉对比没有结果时,会根据新节点的key去对比旧节点数组中的key,从而找到相应旧节点(这里对应的是一个key => index 的map映射)。如果没找到就认为是一个新增节点。而如果没有key,那么就会采用遍历查找的方式去找到对应的旧节点。一种一个map映射,另一种是遍历查找。相比而言。map映射的速度更快。vue部分源码如下:

// vue项目  src/core/vdom/patch.js  -488行// 以下是为了阅读性进行格式化后的代码// oldCh 是一个旧虚拟节点数组if (isUndef(oldKeyToIdx)) {oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx)}if(isDef(newStartVnode.key)) {// map 方式获取idxInOld = oldKeyToIdx[newStartVnode.key]} else {// 遍历方式获取idxInOld = findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx)}

创建map函数

function createKeyToOldIdx (children, beginIdx, endIdx) {let i, keyconst map = {}for (i = beginIdx; i <= endIdx; ++i) {key = children[i].keyif (isDef(key)) map[key] = i}

return map}

遍历寻找

// sameVnode 是对比新旧节点是否相同的函数function findIdxInOld (node, oldCh, start, end) {for (let i = start; i < end; i++) {const c = oldCh[i]if (isDef(c) && sameVnode(node, c)) return i}}

没有绑定key的情况下,并且在遍历模板简单的情况下,会导致虚拟新旧节点对比更快,节点也会复用。而这种复用是就地复用,一种鸭子辩型的复用。以下为简单的例子:

<div id="app"><div v-for="i in dataList">{{ i }}div>div>
var vm = new Vue({el: '#app',data: {dataList: [1, 2, 3, 4, 5]}})

以上的例子,v-for的内容会生成以下的dom节点数组,我们给每一个节点标记一个身份id:

 ['
1

', // id:A'

2

', // id:  B'

3

', // id:  C'

4

', // id:  D'

5

' // id:  E]

  1. 改变dataList数据,进行数据位置替换,对比改变后的数据

 vm.dataList = [4, 1, 3, 5, 2] // 数据位置替换// 没有key的情况, 节点位置不变,但是节点innerText内容更新了['
4

', // id:A'

1

', // id:  B'

3

', // id:  C'

5

', // id:  D'

2

' // id:  E]// 有key的情况,dom节点位置进行了交换,但是内容没有更新//

{{ i }}

['

4

', // id:D'

1

', // id:  A'

3

', // id:  C'

5

', // id:  E'

2

' // id:  B]

增删dataList列表项

vm.dataList = [3, 4, 5, 6, 7] // 数据进行增删// 1. 没有key的情况, 节点位置不变,内容也更新了['
3

', // id:A'

4

', // id:  B'

5

', // id:  C'

6

', // id:  D'

7

' // id:  E]// 2. 有key的情况, 节点删除了 A, B 节点,新增了 F, G 节点//

{{ i }}

['

3

', // id:C'

4

', // id:  D'

5

', // id:  E'

6

', // id:  F'

7

' // id:  G]

从以上来看,不带有key,并且使用简单的模板,基于这个前提下,可以更有效的复用节点,diff速度来看也是不带key更加快速的,因为带key在增删节点上有耗时。这就是vue文档所说的默认模式。但是这个并不是key作用,而是没有key的情况下可以对节点就地复用,提高性能。

这种模式会带来一些隐藏的副作用,比如可能不会产生过渡效果,或者在某些节点有绑定数据(表单)状态,会出现状态错位。VUE文档也说明了 这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出

END

温馨提示

如果你喜欢本文,请分享到朋友圈,想要获得更多信息,请关注我。

c++提取map key_写 React / Vue 项目时为什么要在列表组件中写 key,其作用是什么?...相关推荐

  1. 【建议收藏】使用 Netlify 教你免费将React/Vue项目上线!(前端自动化部署服务)

    背景 想必大家做项目的时候都会遇到项目上线问题吧,项目上线,首先会考虑服务器对吧,对于学生党来说倒还好,购买学生服务器不会花很多钱.其次,我一个前端的居然搞着运维的事情?可不可以简便一点,不要那么复杂 ...

  2. [vue] 组件中写name选项有什么作用?

    [vue] 组件中写name选项有什么作用? 项目使用keep-alive时,可搭配组件name进行缓存过滤 DOM做递归组件时需要调用自身name vue-devtools调试工具里显示的组见名称是 ...

  3. [vue-cli]在使用vue-cli开发vue项目时,自动刷新页面的原理你了解吗?

    [vue-cli]在使用vue-cli开发vue项目时,自动刷新页面的原理你了解吗? 自动刷新页面并不是vue-cli的功能,而是webpack的hot-module-replacement-plug ...

  4. 运行VUE项目时,出现npm ERR! A complete log of this run can be found in:...报错

    运行VUE项目时,出现npm ERR! A complete log of this run can be found in:报错时,分享以下一种解决方案. 本机的 node版本如下 解决方法 1. ...

  5. 创建vue项目时存在的问题及解决方法

    ​ 我在创建一个vue项目时,在这几步之后 ​​​​ ​​ 出现了这样的问题一排 " npm ERR!- npm ERR!- npm ERR!- npm ERR!- npm ERR! -&q ...

  6. 解决使用webstorm新建vue项目时‘gyp: No Xcode or CLT version detected!’报错

    在使用webstorm新建vue项目时,遇到了下面的错误 No receipt for 'com.apple.pkg.CLTools_Executables' found at '/'.No rece ...

  7. 解决VScode创建Vue项目时一直显示downloading template的问题

    问题描述: 本人小白菜在使用VScode创建Vue项目时,界面一直出现downloading template,最后创建失败,查了诸多原因,最后终于通过改变网络连接解决了问题 解决方案: 之前连接的是 ...

  8. 在运行vue项目时发生这种 Cannot find module ‘xxxxx‘ ,解决办法?

    在运行vue项目时发生这种 Cannot find module 'xxxxx' ,解决办法? 首先,在文件夹中删除掉node_modules文件和package-lock.json文件 其次,在使用 ...

  9. vue项目js文件引入第三方库组件

    vue项目js文件引入第三方库组件 //首先按需引入 第三方库 import { MessageBox } from 'element-ui' 使用: MessageBox.alert(`<di ...

  10. vue项目如何在data里调用methods中的方法

    vue项目如何在data里调用methods中的方法 比如使用swiper组件在data里调用methods中函数的方式:data在vue项目里实际也是个函数,所以只要如下操作就行: data() { ...

最新文章

  1. Fragment之间的通信
  2. linux入门(二)
  3. SAP系统财务模块的集团公司处理模式
  4. SQL数据分析实战:好用的窗口函数
  5. 解析xml的4种方法详解
  6. 宽带和流量是分开的吗_为什么现在的手机套餐与宽带越来越贵,只是因为建设5G吗?...
  7. dry的原理_速干面料的原理
  8. Linux 手势识别,基于嵌入式Linux的手势识别技术研究
  9. 6.GD32F103C8T6 定时器的基本使用
  10. Gtk的entry传递数据到内部程序
  11. Flink 如何支持特征工程、在线学习、在线预测等 AI 场景?
  12. 送给女朋友的情人节礼物---超贴心小程序
  13. IDEA 常用快捷键与设置
  14. java命名规则及规范
  15. 为什么html中图片显示不出来,网页图片显示不出来是什么原因?
  16. 单位旧计算机处理,单位出售旧电脑增值税税率是多少?
  17. 无人机/FPV穿越机航模的遥控器/接收机等配件厂商
  18. 关于视频图像dither
  19. html5加载vr视频格式,VR视频格式是什么_VR视频有什么格式_怎么分辨VR视频格式-VR之家...
  20. MATLAB坐标轴位置调整

热门文章

  1. Java基础:Map
  2. LeetCode:每日一题(2020.4.8)
  3. 删除python读取的txt每一行尾部的\n
  4. 机器学习笔记【二】逻辑回归与分类(1):逻辑回归参数更新规则以及pytorch实现
  5. markdown_Latex各种符号
  6. C++中的文件输入/输出
  7. ICCV 2021 | 超越MobileNetV3!SkipNet:面向轻量级CNN的Bias Loss
  8. PCL点云参数估计算法之RANSAC和LMEDS
  9. 帝国CMS-后台管理工具
  10. [译]C#7 Pattern Matching