浅谈Vue3中key的作用和工作原理

这个key属性有什么作用呢?我们先来看一下官方的解释:

  • kekey属性主要用在Vue的虚拟DOM diff算法中,在新旧nodes对比时辨识Vnodes;
  • 如果不使用key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法
  • 而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除/销毁 key 不存在的元素。

先简单提一下我对VNode的理解:

  • VNode的全称是Virtual Node,也就是虚拟节点;
  • Vnode的本质是一个JavaScript的对象;
  • 实际上在Vue中,无论是组件还是单个元素,都表示成了一个个VNode。

举个例子:

<div class="title" style="color: red;">Helllo World</div>
// 实际上在Vue中会表示为:
const VNode = {
    type: "div",
    props: {
        class: "title",
        style: {
            color: "red"
        }
    },
    children: "Hello World" // 假如div里面还包含着其他标签,那么会以同样的方式转成在children里面
}

在什么情况下,插入f效率是最高的呢?

思路:

  • 重新渲染一次(消耗大量性能)
  • 前面的VNode不变,从插入位置重新渲染(消耗较大性能)
  • 所有的VNnode都重新渲染,只需插入新增VNode(性能最好)

结论:想要最高性能,那么必须给新旧VNodes进行key标识,通过key值把旧的VNodes与新的VNodes进行对比,想办法找出需要增加的或者删除的是哪个VNode,其他的VNode尽量不变,那么新旧VNodes对比的这个过程就是diff算法。

Vue事实上会对于有key和没有key会调用两个不同的方法,下面我们来看看源码:(packages\runtime-core\src\renderer)

在有key的情况,执行 patchKeyedChildren方法:

没有key值,执行 patchUnkeyedChildren方法:

注意:当没有key值时,列表过多,也会依次进行patch,会消耗大量性能,那么加上key值后就会节省很多性能损耗。

结论:

所以 key值 是在DOM树进行diff算法时候发挥作用,一个是用来判断新旧 Vnode 是否为同一个,从而进行下一步的比较以及渲染,另外一个作用就是判断组件是否可以复用,是否需要重新渲染。

到此这篇关于Vue3中key的作用和工作原理的文章就介绍到这了,更多相关Vue3中key的作用和工作原理内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 基于vue--key值的特殊用处详解

    数组的v-for item in items item of items item,index in items (item,index) in items 对象的v-for(键值,键名,索引) value in object (value, key) in object (value, key, index) in object v-for渲染的列表的结构采用"就地复用"的策略,也就说当数据重新排列数据时,会复用已在页面渲染好的元素,不会移动 DOM 元素来匹配数据项的顺序,这种模式

  • 浅谈VUE中演示v-for为什么要加key

    说到这个问题想必要举个例子了 没有key <div id="app"> <div> <input type="text" v-model="name"> <button @click="add">添加</button> </div> <ul> <li v-for="(item, i) in list"> <

  • vue 监听键盘回车事件详解 @keyup.enter || @keyup.enter.native

    vue运行为v-on在监听键盘事件时,添加了特殊的键盘修饰符: <input v-on:keyup.13="submit"> vue还非常贴心地给出了常用按键的别名,这样就不必去记keyCode ~ ~ 上面代码,还可以在这样写: <input v-on:keyup.enter="submit"> <input @keyup.enter="submit"> 全部的键盘别名: .enter .tab .delet

  • 使用vue for时为什么要key【推荐】

    前言: 用vue框架写前端代码时经常会用用到v-for这个方法,但使用此方法时vue推荐我们加上一个唯一标识key这是为什么呢?阅读了网上各位大神的文章以及自己的一些理解对这个问题有了新的认识.所以记录下来,若各位看官看到文章里面有错误的地方请指正一下.谢谢各位大佬. 一.diff算法 修改渲染真实的dom会引起整个dom树的重绘和重排.diff算法可以帮助我们只对我们想要修改的部分进行更新而不会引起整个dom树的重绘和重排. 我们先根据dom生成virtual DOM,当virtual Dom

  • Vue中的v-for循环key属性注意事项小结

    当Vue用 v-for 正在更新已渲染过的元素列表是,它默认用"就地复用"策略.如果数据项的顺序被改变,Vue将不是移动DOM元素来匹配数据项的改变,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素. 为了给Vue一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性.key属性的类型只能为 string或者number类型. 在下面这个例子中,如果不给 p 元素绑定key,我先选中第一个, 然后输入ID和Nam

  • 如何正确理解vue中的key详解

    就目前所了解的情况,key的作用有以下这些. v-for遍历时,用id,uuid之类作为key,唯一标识节点加速虚拟DOM渲染 响应式系统没有监听到的数据,用+new Date()生成的时间戳作为key,手动强制触发重新渲染 场景一大同小异司空见惯,场景二是下面这样的: <div :key="rerender"> <span>Hello Vue.js !</span> <complexComponent :propObj="propO

  • 浅谈Vue3中key的作用和工作原理

    这个key属性有什么作用呢?我们先来看一下官方的解释: kekey属性主要用在Vue的虚拟DOM diff算法中,在新旧nodes对比时辨识Vnodes: 如果不使用key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法 而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除/销毁 key 不存在的元素. 先简单提一下我对VNode的理解: VNode的全称是Virtual Node,也就是虚拟节点: Vnode的本质是一个JavaScri

  • 浅谈Vue3 defineComponent有什么作用

    目录 defineComponent重载函数 开发实践 defineComponent函数,只是对setup函数进行封装,返回options的对象: export function defineComponent(options: unknown) { return isFunction(options) ? { setup: options } : options } defineComponent最重要的是:在TypeScript下,给予了组件 正确的参数类型推断 . defineCompo

  • 浅谈Vue3中watchEffect的具体用法

    前言 watchEffect,它立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数. 换句话说:watchEffect相当于将watch 的依赖源和回调函数合并,当任何你有用到的响应式依赖更新时,该回调函数便会重新执行.不同于 watch,watchEffect 的回调函数会被立即执行(即 { immediate: true }) 此文主要讲述怎样利用清除副作用使我们的代码更加优雅~ watchEffect的副作用 什么是副作用(side effect),简单的说副作用

  • 浅谈vue3中ref、toRef、toRefs 和 reactive的区别

    目录 一.ref——定义任意类型响应式数据 二.reactive——定义响应式对象 三.toRef——将一个 reactive 转化为一个 ref 四.toRefs——将多个 reactive 自动解构为多个 ref 一.ref——定义任意类型响应式数据 ref 能定义“任何类型”的响应式数据(ref 在 vue3 中指响应式数据). 参数可以传入任意数据类型. 使用 ref 定义的属性必须通过 .value 的形式才能修改其值.属性的值一旦被修改就会触发模板的重新渲染以显示最新的值. 对于在

  • 浅谈vue3中effect与computed的亲密关系

    在我刚看完vue3响应式的时候,心中就有一个不可磨灭的谜团,让我茶不思饭不想,总想生病.那么这个谜团是什么呢?就是在响应式中一直穿行在tranger跟track之间的effect.如果单纯的响应式原理根本就用不上effect,那么effect到底是干什么的呢? 船到桥头自然直,柳岸花明又一村.苦心人天不负,偶然间我看到了effect测试代码用例! it('should observe basic properties', () => { let dummy const counter = rea

  • 浅谈Java日志框架slf4j作用及其实现原理

    SLF4J是一个日志框架抽象层,底下绑定具体的日志框架,比如说Log4J,Logback,Java Logging API等.SLF4J也有自身的默认实现,但是我们还是主要以日志框架抽象层的身份使用SLF4J. 要使用SLF4J,得包含对"org.slf4j:slf4j-api"的依赖. 简单回顾门面模式 slf4j是门面模式的典型应用,因此在讲slf4j前,我们先简单回顾一下门面模式, 门面模式,其核心为外部与一个子系统的通信必须通过一个统一的外观对象进行,使得子系统更易于使用.用一

  • 浅谈vue中数据双向绑定的实现原理

    vue中最常见的属v-model这个数据双向绑定了,很好奇它是如何实现的呢?尝试着用原生的JS去实现一下. 首先大致学习了解下Object.defineProperty()这个东东吧! * Object.defineProperty() * 对对象的属性进行 定义/修改 * */ let obj = {x:10} // 这两种方式都相对来说比较简单,直接,但是有些时候我们需要对对象的属性的修改和增加进行必要的干预 // obj.y = 20; // obj.x = 100; // obj.x =

  • 浅谈Jquery中Ajax异步请求中的async参数的作用

    之前不知道这个参数的作用,上网找了前辈的博客,在此收录到自己的博客,希望能帮到更多的朋友: test.html <a href="javascript:void(0)" onmouseover="testAsync()"> asy.js function testAsync{ var temp; $.ajax({ async: false, type : "GET", url : 'tet.php', complete: functi

  • 浅谈ubuntu 中sudo update与upgrade的作用及区别

    入门linux的同志,刚开始最迫切想知道的,大概一个是中文输入法,另一个就是怎么安装软件.本文主要讲一下LINUX安装软件方面的特点. 在windows下安装软件,我们只需要有EXE文件,然后双击,下一步直接OK就可以了.但在LINUX下,不是这样的.每个LINUX的发行版,比如Ubuntu,都会维护一个自己的软件仓库,我们常用的几乎所有软件都在这里面.这里面的软件绝对安全,而且绝对的能正常安装. 那我们要怎么安装呢?在UBUNTU下,我们维护一个源列表,源列表里面都是一些网址信息,这每一条网址

  • 浅谈es6中export和export default的作用及区别

    作用: export和export default实现的功能相同,即:可用于导出(暴露)常量.函数.文件.模块等,以便其他文件调用. 区别: 1.export导出多个对象,export default只能导出一个对象 2.export导出对象需要用{ },export default不需要{ },如: export {A,B,C}; export default A; 3.在其他文件引用export default导出的对象时不一定使用导出时的名字.因为这种方式实际上是将该导出对象设置为默认导出

随机推荐