iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >vue中设置key与不设置有什么区别
  • 197
分享到

vue中设置key与不设置有什么区别

2023-06-30 15:06:16 197人浏览 安东尼
摘要

本文小编为大家详细介绍“Vue中设置key与不设置有什么区别”,内容详细,步骤清晰,细节处理妥当,希望这篇“vue中设置key与不设置有什么区别”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、Key是什么开始之

本文小编为大家详细介绍“Vue中设置key与不设置有什么区别”,内容详细,步骤清晰,细节处理妥当,希望这篇“vue中设置key与不设置有什么区别”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

vue中设置key与不设置有什么区别

一、Key是什么

开始之前,我们先还原两个实际工作场景

  • 当我们在使用v-for时,需要给单元加上key

<ul>    <li v-for="item in items" :key="item.id">...</li></ul>
  • +new Date()生成的时间戳作为key,手动强制触发重新渲染

<Comp :key="+new Date()" />

那么这背后的逻辑是什么,key的作用又是什么?

一句话来讲

key是给每一个vnode的唯一id,也是diff的一种优化策略,可以根据key,更准确, 更快的找到对应的vnode节点。

场景背后的逻辑

当我们在使用v-for时,需要给单元加上key

  • 如果不用key,Vue会采用就地复地原则:最小化element的移动,并且会尝试尽最大程度在同适当的地方对相同类型的element,做patch或者reuse。

  • 如果使用了key,Vue会根据keys的顺序记录element,曾经拥有了key的element如果不再出现的话,会被直接remove或者destoryed

+new Date()生成的时间戳作为key,手动强制触发重新渲染

  • 当拥有新值的rerender作为key时,拥有了新key的Comp出现了,那么旧key Comp会被移除,新key Comp触发渲染

二、设置key与不设置key区别

举个例子:
创建一个实例,2秒后往items数组插入数据

<body>  <div id="demo">    <p v-for="item in items" :key="item">{{item}}</p>  </div>  <script src="../../dist/vue.js"></script>  <script>    // 创建实例    const app = new Vue({      el: '#demo',      data: { items: ['a', 'b', 'c', 'd', 'e'] },      mounted () {        setTimeout(() => {           this.items.splice(2, 0, 'f')  //        }, 2000);     },   });  </script></body>

在不使用key的情况,vue会进行这样的操作:

vue中设置key与不设置有什么区别

分析下整体流程:

  • 比较A,A,相同类型的节点,进行patch,但数据相同,不发生dom操作

  • 比较B,B,相同类型的节点,进行patch,但数据相同,不发生dom操作

  • 比较C,F,相同类型的节点,进行patch,数据不同,发生dom操作

  • 比较D,C,相同类型的节点,进行patch,数据不同,发生dom操作

  • 比较E,D,相同类型的节点,进行patch,数据不同,发生dom操作

  • 循环结束,将E插入到DOM

一共发生了3次更新,1次插入操作

在使用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 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升

三、原理分析

源码位置:core/vdom/patch.js

里判断是否为同一个key,首先判断的是key值是否相等如果没有设置key,那么keyundefined,这时候undefined是恒等于undefined

function sameVnode (a, b) {    return (        a.key === b.key && (            (                a.tag === b.tag &&                a.isComment === b.isComment &&                isDef(a.data) === isDef(b.data) &&                sameInputType(a, b)            ) || (                isTrue(a.isAsyncPlaceholder) &&                a.asyncFactory === b.asyncFactory &&                isUndef(b.asyncFactory.error)            )        )    )}

updateChildren方法中会对新旧vnode进行diff,然后将比对出的结果用来更新真实的DOM

function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) {    ...    while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {        if (isUndef(oldStartVnode)) {            ...        } else if (isUndef(oldEndVnode)) {            ...        } else if (sameVnode(oldStartVnode, newStartVnode)) {            ...        } else if (sameVnode(oldEndVnode, newEndVnode)) {            ...        } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right            ...        } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left            ...        } else {            if (isUndef(oldKeyToIdx)) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx)            idxInOld = isDef(newStartVnode.key)                ? oldKeyToIdx[newStartVnode.key]                : findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx)            if (isUndef(idxInOld)) { // New element                createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)            } else {                vnodeToMove = oldCh[idxInOld]                if (sameVnode(vnodeToMove, newStartVnode)) {                    patchVnode(vnodeToMove, newStartVnode, insertedVnodeQueue, newCh, newStartIdx)                    oldCh[idxInOld] = undefined                    canMove && nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm)                } else {                    // same key but different element. treat as new element                    createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)                }            }            newStartVnode = newCh[++newStartIdx]        }    }    ...}

读到这里,这篇“vue中设置key与不设置有什么区别”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网精选频道。

--结束END--

本文标题: vue中设置key与不设置有什么区别

本文链接: https://www.lsjlt.com/news/329765.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • vue中设置key与不设置有什么区别
    本文小编为大家详细介绍“vue中设置key与不设置有什么区别”,内容详细,步骤清晰,细节处理妥当,希望这篇“vue中设置key与不设置有什么区别”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、Key是什么开始之...
    99+
    2023-06-30
  • key与index在Mysql中有什么区别
    本篇文章给大家分享的是有关key与index在Mysql中有什么区别,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。我们先来看下代码:ALTER...
    99+
    2024-04-02
  • Java与Unix Shell之间的路径设置有什么区别?
    Java和Unix Shell是两种不同的编程语言,它们在路径设置上有一些区别。本文将探讨Java和Unix Shell之间的路径设置有什么区别,并提供一些示例代码以帮助读者更好地理解。 Java的路径设置 Java是一种面向对象的编程语言...
    99+
    2023-10-12
    unix shell path
  • angular与vue有什么区别
    angular与vue的区别:1、学习曲线,Angular是一个完整的框架,学习曲线相对较陡峭,Vue是更简单容易上手的框架;2、性能,Angular在处理大型应用程序时表现出色,Vue是响应式的机制来追踪数据的变化;3、生态系统,Angu...
    99+
    2023-08-10
  • redis怎么设置key的有效期
    这篇文章主要介绍“redis怎么设置key的有效期”,在日常操作中,相信很多人在redis怎么设置key的有效期问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”redis怎么设置key的有效期”的疑惑有所帮助!...
    99+
    2023-06-26
  • C++中操作符的前置与后置有什么区别
    目录一、值得思考的问题二、意想不到的事实三、++ 操作符重载四、真正的区别五、小结一、值得思考的问题 下面的代码有没有区别?为什么? 二、意想不到的事实 现代编译器产品会对代码进行...
    99+
    2024-04-02
  • Vuex与Pinia在设计与实现上有什么区别
    本篇内容主要讲解“Vuex与Pinia在设计与实现上有什么区别”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Vuex与Pinia在设计与实现上有什么区别”吧!Vue 状态管理首先,先介绍一下 V...
    99+
    2023-07-04
  • C++前置++与后置++的区别是什么
    这篇文章主要讲解了“C++前置++与后置++的区别是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++前置++与后置++的区别是什么”吧!前置++:type operator...
    99+
    2023-06-17
  • VUE中的v-if与v-show有什么区别
    这篇文章将为大家详细讲解有关VUE中的v-if与v-show有什么区别,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1.共同点都是动态显示DOM元素2.区别(1)手段:v-if是动态的向DOM树内添加或者...
    99+
    2023-06-29
  • vue中使用slot与slot-scope有什么区别
    本文小编为大家详细介绍“vue中使用slot与slot-scope有什么区别”,内容详细,步骤清晰,细节处理妥当,希望这篇“vue中使用slot与slot-scope有什么区别”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习...
    99+
    2023-07-04
  • Redis中怎么设置过期时间的Key
    Redis中怎么设置过期时间的Key,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1、 DEL/SET/GETSET等命令会清除过期时间在使用...
    99+
    2024-04-02
  • php中怎么设置时区
    今天就跟大家聊聊有关php中怎么设置时区,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。PHP中设置时区方法小结代码如下:< date_defa...
    99+
    2024-04-02
  • vue相对路径与路径别名如何设置
    这篇文章主要介绍“vue相对路径与路径别名如何设置”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“vue相对路径与路径别名如何设置”文章能帮助大家解决问题。@ ~ 相对路径 路径别名设置./这是相对路...
    99+
    2023-06-30
  • $*与$@中Shell中有什么区别
    这篇文章给大家介绍$*与$@中Shell中有什么区别,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。当 $* 和 $@ 不被双引号" "包围时,它们之间没有任何区别,都是将接收到的每个参数看做一份数据...
    99+
    2023-06-06
  • C++中NULL与nullptr的区别有什么不同
    这篇文章主要介绍C++中NULL与nullptr的区别有什么不同,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、C程序中的NULL在C语言中,NULL通常被定义为:#define NULL ((void *)0)所...
    99+
    2023-06-15
  • MySQL中设置时区的方法是什么
    在 MySQL 中设置时区的方法有两种: 使用 SET 语句设置时区: SET time_zone = 'Asia/S...
    99+
    2024-04-09
    MySQL
  • 怎么在redis中设置key的过期时间
    在redis中设置key过期时间的方法:1.启动redis服务;2.登录redis数据库;3.执行命令设置过期时间;具体步骤如下:首先,在命令行中启动redis服务;service redis start mysql服务启动后,输入用户名,...
    99+
    2024-04-02
  • css中使用rgba和opacity设置透明度的区别是什么
    这篇文章将为大家详细讲解有关css中使用rgba和opacity设置透明度的区别是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1.使用rgba设置背景色的透明效果如...
    99+
    2024-04-02
  • Vue设置keepAlive不生效怎么解决
    本篇内容主要讲解“Vue设置keepAlive不生效怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Vue设置keepAlive不生效怎么解决”吧!设置keepAlive不生效如演示,Vu...
    99+
    2023-06-30
  • Vue中Ref与Reactive的区别是什么
    今天小编给大家分享一下Vue中Ref与Reactive的区别是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Ref与Re...
    99+
    2023-06-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作