在写vue的项目中为什么index不能做key使用?

news2024/12/24 11:13:17

前言

在我们写vue的的项目时,我们是否会疑惑后端数据为什么都会带一个Id,而这个Id一般都作为循环中的key来使用,我们为什么不直接用index来作为他的key呢?这样不是更方便吗?下面我就带大家解决解决这和疑惑吧。

key的作用

在解决这个疑惑之前,我们先来了解了解key在循环中的作用吧。

1、key是唯一标识,它作用主要是为了更高效的让diff算法更准确的找到需要被对比的两个结点。

2、Vue在patch过程中判断两个节点是否是相同节点key是必要条件,渲染一组列表时,key是作为唯一标识,所以如果不定义key的话,Vue只能认为比较的两个节点是同一个,导致了频繁更新元素,使得整个patch(diff算法)过程比较低效,影响性能。

3、在实际的使用中在渲染一组列表时key必须设置,而且必须是唯一标识(所以不能用随机数做key),应该避免使用index作为key,因为会导致一些隐蔽的bug;Vue中在使用相同标签元素过渡切换时,也会使用key属性,其目的也是为了让Vue可以区分它们,否则Vue只会替换其内部属性而不会触发过渡效果。

虚拟DOM树

简单来说,虚拟DOM树就是一个对象而已, 其中描述了每一层容器的特征。

其主要是利用 js 描述元素与元素的关系,用 js 对象去表示真实的 DOM 树结构,创建一个虚拟 DOM 对象 以便内在浏览器中操作数据的改变。

vue在组件渲染的时候会在生命周期中调用 render 函数,这个函数也会生成一个虚拟 dom,再根据这个虚拟 dom 生成真实的 dom,然后这个真实的 dom 会挂载到页面中。

如果组件内有响应的数据,数据发生改变的时候 render 函数会生成一个新的虚拟 dom, 新的虚拟 dom 树会去使用diff算法去和旧的虚拟 dom 树进行对比,找到要要修改的虚拟 dom 的部分,去修改相对应部分的真实 dom,在将真实dom挂载到页面中。

diff算法

1.diff算法diff算法就是进行虚拟节点对比,并返回一个patch对象,用来存储两个节点不同的地方,最后用patch记录的消息去局部更新Dom。

2.diff算法就是用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到页面中。

3.当中当状态变更的时候,diff算法又会重新执行,构造一棵新的虚拟DOM树结构。然后用新的树和旧的树进行比较,记录两棵树差异,同时把新的DOM树所记录的差异应用到旧的DOM树中,然后再构建的真正的DOM树上,实现了视图的更新

index不能作为key的两种demo情况

deom1

<body>
    <div id="app">
        <ul>
            <item v-for="(num, index) in list" :key="num.id" || :key ='id'
            :num="num.num" :class="`item${num.num}`"></item>
        </ul>
        <button @click="change">change</button>
    </div>
    <script> new Vue({
            el: '#app',
            data() {
                return {
                    list: [
                        {id:1, num:1},
                        {id:2, num:2},
                        {id:3, num:3},
                    ]
                }
            },
            methods: {
                change(){
                    this.list.reverse()
                }
            },
            components: {
                item: {
                    props:['num'],
                    template:`
                    <div>
                        {{
                        num
                        }}
                    </div>
                },
                name:'child'
            }
        }) </script>
</body> 

我们先来说说demo1,我们来看看用index和id做key值其内部的虚拟DOM结构发生的变化。

所以用index作为key会导致diff 中的优化失效(降低了复用性,违背了虚拟DOM的初衷)

demo2

<body>
  <div id="app">
    <ul>
      <li v-for="(num, index) in list" :key="index">
        <item/>
      </li>
    </ul>
    <button @click="del">del</button>
  </div>
  <script> new Vue({
      el: '#app',
      data() {
        return {
          list: [ 1, 2, 3]
        }
      },
      methods: {
        del() {
          this.list.splice(0, 1)
        }
      },
      components: {
        item: {
          template: '<div>{{Math.random()}}</div>'
        }
      }
    }) </script>
</body> 

在deom2中,当我们要删除列表的第一和值时,如果使用index作为key,会产生严重的bug,同样的,我们先来分析分析他的dom结构。

在我们使用index作为key时,当我们要删除列表的第一个值时,第二个值的key就会向前进一位,而diff算法删除生成的新的DOM树会识别到列表的长度缩短了一位,而直接生成前两两个值的DOM树结构,从而删除了最后一位DOM结点,导致出现bug。而当我们使用id作为key是,diff算法会直接删除对象的key的结点。

所以在删除数据时,因为vue 不会深入的去对比子组件的文本内容,所以会错误移出VDOM中的结点。

总结

介绍完这两种情形下,在我们平常的conding中,为了使我们能按时下班,我们也应该拒绝用index作为key来使用。

最后

最近还整理一份JavaScript与ES的笔记,一共25个重要的知识点,对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识,提升工作效率。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/95610.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习-归一化输入,梯度消失爆炸,梯度检验

文章目录前言一、归一化输入1、均值方差归一化2、why normalize input?二、梯度消失&#xff0c;爆炸1.梯度2.深度网络学习初始化三、梯度检验梯度检验前言 吴恩达 week5 一、归一化输入 1、均值方差归一化 均值方差归一化。 要注意&#xff1a;我们要对训练数据集和测试数…

探花交友_第9章_小视频方案(新版)

探花交友_第9章_小视频方案(新版) 文章目录探花交友_第9章_小视频方案(新版)1. 我的访客1.1 需求分析1.1.1 功能说明1.1.2 数据库表1.2 记录访客数据tanhua-modeltanhua-app-servertanhua-dubbo-interfacetanhua-dubbo-mongo1.3 首页谁看过我需求分析tanhua-modeltanhua-app-se…

小学生 C++画图 Go C 编程 第7课 奇异的花朵

第一课 GoC简介和演示 第一课 GoC简介和演示_ahwhjt的博客-CSDN博客_goc输入图形数量 第二课 了解编程环境 第二课 了解编程环境_ahwhjt的博客-CSDN博客_goc编程环境 第三课 基本绘图命令 第三课 基本绘图命令_ahwhjt的博客-CSDN博客_电脑编程的pen.lt 第四课 变量的引入 第…

重写 Nacos 服务发现:多个服务器如何跨命名空间,访问公共服务?

一、问题背景 在开发某个公共应用时&#xff0c;笔者发现该公共应用的数据是所有测试环境&#xff08;假设存在 dev/dev2/dev3&#xff09;通用的。 这就意味着只需部署一个应用&#xff0c;就能满足所有测试环境的需求&#xff1b;也意味着所有测试环境都需要调用该公共应用…

匆匆遭遇猿如意

刚刚收到一条消息&#xff0c;说有一个csdn的猿如意可以测试了&#xff0c;我就下载了一个&#xff0c;根据提示下载了&#xff0c;然后开始体验。 一、ChatGPT 谁让这个东西最近这么热呢&#xff0c;所以&#xff0c;我第一个就体验这个东东了&#xff0c;结果&#xff0c;结…

excel多条件预算:规划求解工具计算多产品最佳效益组合

江南皮革厂生产三种产品&#xff0c;皮鞋、皮手套、皮帽。三种产品需要原材料甲、乙、丙。近期&#xff0c;原材料供应有限制&#xff0c;生产工时也有限制。已知产品单件的用时、用料、利润&#xff0c;求如何组合产品利润最大。 一、加载规划求解工具 规划求解工具位于“数据…

CN域名隐私保护内测收费

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 据站长DNS Admin爆料&#xff0c;CNNIC向西部数码发布通知称&#xff0c;内测的CN域名WHOIS隐私保护服务即将暂停免费政策&#xff0c;继续使用将收取相应服务费用&#xff0c;价格为48元/个/年。 …

电脑重装系统后会闪屏是什么原因

​电脑的显示屏是我们日常使用电脑最常使用的硬件之一&#xff0c;可以说使用电脑必备的就是显示屏了。而显示屏在使用的过程中也会出现各种各样的问题&#xff0c;最近就有不少用户反应自己的电脑出现了黑屏闪烁的问题。 软件原因&#xff1a; 一、检查显示刷新率设置是否正确…

RTMP推流方案总结

由于项目需要 RTMP 推送 H264 数据&#xff0c;在网上查找了下相关的方案&#xff0c;总结一下。 RTMP协议简介 在总结之前&#xff0c;我们先简单介绍一下 RTMP 协议。 RTMP(Real Time Messaging Protocol) 实时消息传送协议是 Adobe Systems 公司为 Flash 播放器和服务器之间…

外卖订餐系统的设计与实现/点餐订餐系统

摘 要 随着外卖订餐在高校越来越普及&#xff0c;传统的电话订餐给顾客跟商家带来不方便,如何使订餐更快速&#xff0c;更方便已成为众多高校学生关注的问题了。本外卖订餐系统是针对高校商家进行具体的需求分析&#xff0c;采用JSP技术和采用SSM框架&#xff0c;MYSQL数据库…

QT制作窗口切换的小程序

QT制作窗口切换的小程序 前言&#xff1a;本次实验是在三个窗口之间自由切换&#xff0c;窗口中播放gif格式的动态图。 让我们先来看看使用到的主要的函数&#xff1a; 一、播放gif格式动态图的函数 QMovie *movie new QMovie("../form/1.gif"); // "../f…

软件测试人到30岁+,在岗位上工作如何破局?

最近一个学生也可以说是朋友&#xff0c;他遇到了一个让他困扰的职场难题&#xff0c;背景如下&#xff1a; 1&#xff09;他们公司准备搞 安全测试 了&#xff0c;现在有人员培训的计划&#xff0c;所以全组有学习安全测试课程的安排。 2&#xff09;他自己目前专职性能测试…

12月17日第壹简报,星期六,农历十一月廿四

12月17日第壹简报&#xff0c;星期六&#xff0c;农历十一月廿四1. 数字人民币试点再扩容&#xff1a;粤苏冀川4省全覆盖&#xff0c;新增济南、南宁、昆明等5座城市。2. 人民币兑美元中间价调降448点至6.9791&#xff0c;降幅创5月27日以来最大。3. 政府出面站台、鼓励居民团购…

DropBox系列-安卓DropBox介绍

前言&#xff1a; 作者本人负责公司的APM监控模块&#xff0c;因为工作的原因&#xff0c;对ANR&#xff0c;crash等流程研究的比较多&#xff0c;最近在打造APM监控平台的时候&#xff0c;顺带对DropBox的实现原理进行了一定的学习和研究&#xff0c;发现了一些妙用&#xff…

Dubbo 1 分布式系统中的相关概念 1.3 架构演进

Dubbo 【黑马程序员Dubbo快速入门&#xff0c;Java分布式框架dubbo教程】 1 分布式系统中的相关概念 文章目录Dubbo1 分布式系统中的相关概念1.3 架构演进1.3.1 架构演进1.3.2 架构演进 - 单体架构1.3.3 架构演进 - 垂直架构1.3.4 架构演进 - 分布式架构1.3.5 架构演进 - SOA…

SPDK块设备

SPDK视角每个App由多个子系统(subsystem)构成&#xff0c;同时每个子系统又包含多个模块(module)&#xff0c;子系统和模块的注入都是可插拔的&#xff0c;通过相关的宏定义声明集成到SPDK组件容器里(其中子系统的注入可通过声明SPDK_SUBSYSTEM_REGISTER&#xff0c;块设备模块…

5G小基站行业市场空间将持续释放 2024年或将迎来建设高峰期

5G小基站行业上游包括硬件资源供应商、软件资源供应商、配套资源供应商&#xff1b;中游主体包括5G小基站设备厂商、5G小基站解决方案服务商&#xff1b;下游则主要是大型写字楼、购物中心、机场等。 数据来源&#xff1a;中国5G小基站市场发展趋势分析与未来前景研究报告&…

弥漫的烟圈-Abaqus涡环仿真与空气大炮

今天简单地讨论一下这个有趣的流体现象-烟圈&#xff0c;并使用Abaqus欧拉分析对它的形成过程进行仿真&#xff0c;揭示其中的力学奥秘。 烟圈 喷气圈的海豚 在流体力学里面&#xff0c;烟圈和水下气圈有个共同的名字&#xff0c;叫做Vortex Ring&#xff0c;即涡环或环形涡流…

腾讯云服务器选购新手教程(新版流程超级详细)

腾讯云服务器选购新手教程(新版流程超级详细)&#xff0c;来详细说下腾讯云服务器购买流程图文详解及购买渠道说明。 腾讯云服务器购买流程 购买腾讯云服务器很简单&#xff0c;首先你需要注册一个腾讯云账号&#xff0c;使用微信或QQ注册即可&#xff0c;很简单。账号注册后&…

git clone 拉取远程仓库

1. git clone 拉取仓库 2. 以 HTTPS 方式拉取仓库 3. 以 SSH 方式拉取仓库 1. git clone 拉取仓库 拉取远程库的默认分支 git clone <repositories> 拉取远程库的指定分支 -b, --branch git clone -b <branch> <repositories> 将远程库拉取到指定目录 git c…