vue2-vue中key的原理

news2024/9/23 11:13:40

vue中key是什么?它有什么作用?原理是什么?
1、key是什么?
先考虑两个实际场景
当我们使用v-for时,需要给单元加上key
在这里插入图片描述
用+new Date()生成的时间戳作为key,手动强制触发重新渲染。
在这里插入图片描述
在上面两种场景中,key的作用是:
key是给每一个vnode的唯一id,也是diff的一种优化策略,可以根据key,更快,更准确的找到对应vnode节点

场景背后的逻辑:
当我们在使用v-for的时候,需要给单元加上key
如果不使用key,Vue会采用旧地复地原则:最小化element的移动,并且会尝试最大程度在同适当的地方对相同类型的element,做patch或resue
如果使用了key,Vue会根据keys的顺序记录element,曾经拥有了key的element如果不再出现的话,会被直接remove或者destroy

用+new Data()生成的时间戳作为key,手动强制触发重新渲染
当拥有新值的rerender作为key时,拥有了新key的Comp出现了,那么旧的key Comp就会被移除,新key Comp触发渲染

2、设置key与不设置key的区别
举个例子:创建一个实例,2秒后往items数组插入数据
在这里插入图片描述
在不使用key的情况,vue会进行这样的操作。
在这里插入图片描述
整体流程:
比较A A,相同类型的节点,进行patch,但数据相同,不发生DOM操作
比较B B,相同类型的节点,进行patch,但数据相同,不发生DOM操作
比较C F,相同类型的节点,进行patch,数据不同,发生DOM操作
比较D C,相同类型的节点,进行patch,数据不同,发生DOM操作
比较E D,相同类型的节点,进行patch,数据不同,发生DOM操作
循环结束,将E插入到DOM中
一共发生了三次更新,一次插入操作

在使用key的情况,vue会进行这样的操作。
比较A A,相同类型的节点,进行patch,但数据相同,不发生DOM操作
比较B B,相同类型的节点,进行patch,但数据相同,不发生DOM操作
比较C F,不同类型的节点
比较E E,相同类型的节点,进行patch,但数据相同,不发生DOM操作
比较D D ,相同类型的节点,进行patch,但数据相同,不发生DOM操作
比较C C,相同类型的节点,进行patch,但数据相同,不发生DOM操作
循环结束,将F插入到C之前
一共发生了0次更新,1次插入操作

通过上面的例子,可见设置key能够大大减少对页面的DOM操作,提高了diff效率

设置key一定会提高diff效率吗?
不一定,文档中有明确的表示。
当vue.js用v-for正在更新已渲染过的元素列表时,它默认用“就地复用”策略,如果数据项的顺序被改变,vue将不会移动DOM元素来匹配数据项的顺序,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。
这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时DOM状态(例如表单的输入值)的列表渲染输出

建议:尽可能在使用v-for时提供key,除非遍历输出的DOM内容非常简单,或者刻意依赖默认行为以获取性能上的提升。

3、原理分析
源码位置:core/vdom/patch.js
这里判断是否为同一个key,首先判断的是key值是否相等,如果没有设置key,那么key为undefined,这时候,undefined恒等于undefined
在这里插入图片描述
updateChildren方法中会对新旧的vnode进行diff,然后将对比出的结果用来更新真实的DOM
在这里插入图片描述在这里插入图片描述

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

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

相关文章

一百四十三、Linux——Linux的CentOS 7系统语言由中文改成英文

一、目的 之前安装CentOS 7系统的时候把语言设置成中文,结果Linux文件夹命名出现中文乱码的问题,于是决定把Linux系统语言由中文改成英文 二、实施步骤 (一)到etc目录下,找到配置文件locale.conf # cd /etc/ # ls…

总结七大排序!

排序总览 外部排序:依赖硬盘(外部存储器)进行的排序。对于数据集合的要求特别高,只能在特定场合下使用(比如一个省的高考成绩排序)。包括桶排序,基数排序,计数排序,都是o…

C++ STL快速应用

STL 容器 STL容器有共同的操作接口,包括初始化操作、判空、查看大小、比较元素、销毁、交换,这些操作都是一样的接口。 对于访问遍历元素(增删改查),都可以使用迭代器(正向)进行操作&#xff0c…

信号平滑或移动平均滤波研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

【雕爷学编程】Arduino动手做(184)---快餐盒盖,极低成本搭建机器人实验平台2

吃完快餐粥,除了粥的味道不错之外,我对个快餐盒的圆盖子产生了兴趣,能否做个极低成本的简易机器人呢?也许只需要二十元左右 知识点:轮子(wheel) 中国词语。是用不同材料制成的圆形滚动物体。简…

JDK17环境下安装Nacos

1.配置好jdk17环境 命令台java -version显示17版本 2.下载并安装Nacos 下载地址:Releases alibaba/nacos GitHub 安装完本地解压 解压完到nacos的bin目录下,执行.\startup.cmd -m standalone启动即可。 用过好几种方式,比如启动startup…

一百四十五、Kettle——查看Kettle在Windows本地和在Linux上生成的.kettle文件夹位置

(一)目的 查看kettle连数据库后自动生成的.kettle文件夹在Windows本地和在Linux中的位置, 这个文件很重要!!! (二).kettle文件夹在Windows本地的位置 C:\Users\Administrator\.k…

ClickHouse SQL与引擎--基本使用(一)

1.查看所有的数据库 show databases; 2.创建库 CREATE DATABASE zabbix ENGINE Ordinary; ATTACH DATABASE ck_test ENGINE Ordinary;3.创建本地表 CREATE TABLE IF NOT EXISTS test01(id UInt64,name String,time UInt64,age UInt8,flag UInt8 ) ENGINE MergeTree PARTI…

英特尔傲腾CAS报错unknown error cache acceleration software could not start cache

英特尔傲腾CAS报错unknown error cache acceleration software could not start cache 文章目录 英特尔傲腾CAS报错unknown error cache acceleration software could not start cache我是怎么遇到这个问题的我是如何解决的实验步骤打Primo Cache蓝屏补丁拔掉原来的系统盘开关机…

【力扣】21. 合并两个有序链表 <链表指针>

【力扣】21. 合并两个有序链表 将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例1 输入:l1 [1,2,4], l2 [1,3,4] 输出:[1,1,2,3,4,4] 示例 2 输入:l1 [], l2 [] 输出:…

Java List(列表)

List 是一个有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List 集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。List 集合默认按元素的添加顺序设置元素的索引,第一个添加到 List 集合中的元素的索引为 0&#xff…

如何从 Android 设备恢复已删除的文件?

从 Android 设备恢复已删除的文件很简单,但您需要了解内部恢复和SD 卡恢复之间的区别。 目前销售的大多数 Android 设备都配备了 SD 卡插槽(通常为 microSD),可以轻松添加额外的存储空间。该存储空间可用于存储照片、视频、文档&a…

机器学习概述及其主要算法

目录 1、什么是机器学习 2、数据集 2.1、结构 3、算法分类 4、算法简介 4.1、K-近邻算法 4.2、贝叶斯分类 4.3、决策树和随机森林 4.4、逻辑回归 4.5、神经网络 4.6、线性回归 4.7、岭回归 4.8、K-means 5、机器学习开发流程 6、学习框架 1、什么是机器学习 机器…

SprinMVC获取请求参数

SprinMVC获取请求参数 Spring MVC 提供的获取请求参数的方式 通过 HttpServletRequest 获取请求参数通过控制器方法的形参获取请求参数使用 RequestParam 注解获取请求参数通过实体类对象获取请求参数(推荐) 通过ServlstAPI获取 将HttpServletRequest…

Qt开发,去掉Qt生成动态库的版本号

一、问题描述 1、Qt在生成动态库时,于Mac下默认生成带版本号的库,于Windows下默认生成不带版本号的库。 二、问题分析 生成带完整版本号的库文件及相关软链接 三、解决方案 以插件方式生成动态库,在.pro文件中添加以下配置参数 CONFIG …

C高级【day3】

思维导图: 判断家目录下,普通文件的个数和目录文件的个数: #!/bin/bashvar1(ls -l ~/ | cut -d r -f 1 | grep -i -) var2(ls -l ~/ | cut -d r -f 1 | grep -i d) #echo ${var1[*]} #echo ${var2[*]}echo 普通文件个数:${#var…

vue2-$nextTick有什么作用?

1、$nextTick是什么? 官方定义:在下次DOM更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM。 解释:Vue在更新DOM时是异步执行的,当数据发生变化时,Vue将开启一个异步更新的队…

Linux学习之正则表达式元字符和grep命令

cat /etc/redhat-release看到操作系统的版本是CentOS Linux release 7.6.1810 (Core),uname -r可以看到内核版本是3.10.0-957.21.3.el7.x86_64。 正则表达式是一种搜索字符串的模式,通俗点理解,也就是普通字符和元字符共同组成的字符集合匹…

(四)Node.js - npm与包

1. 什么是包 Node.js中的第三方模块又叫做包。 不同于Node.js中的内置模块与自定义模块,包是由第三方个人或团队开发出来的,免费供所有人使用。 由于Node.js的内置模块进提供了一些底层的API,导致在基于内置模块进行项目开发时&#xff0c…

无涯教程-Perl - foreach 语句函数

foreach 循环遍历列表值,并将控制变量(var)依次设置为列表的每个元素- foreach - 语法 Perl编程语言中的 foreach 循环的语法是- foreach var (list) { ... } foreach - 流程图 foreach - 示例 #!/usr/local/bin/perllist(2, 20, 30, 40, 50);# foreach loop ex…