v-for中key的作用与原理
一、虚拟DOM中key的作用
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据新数据生成新的虚拟DOM,随后Vue会对新虚拟DOM与旧虚拟DOM的差异进行比较。
二、如何选择key
最好使用每条数据的唯一标识作为key,用一个简单的例子说明:
1.用index作为key时
点击按钮在列表最前方添加赵六用户
<ul>
<li v-for="(p,index) of persons" :key="index">
{{p.name}}
<input type="text">
</li>
<br>
<button @click="Add">在最前方添加一个用户</button>
</ul>
data () {
return {
persons: [
{id: '01', name: '张三'},
{id: '02', name: '李四'},
{id: '03', name: '王五'}
]
}
},
methods: {
Add () {
let p = {id: '04', name: '赵六'}
this.persons.unshift(p)
}
}
点击以后,页面如下图

然而,如果在我点击按钮前,在输入框中输入一些内容

点击按钮后就会变成

很明显,这并不是我们理想中想要呈现的效果。
2.用id作为key时
<ul>
<li v-for="p of persons" :key="p.id">
{{p.name}}
<input type="text">
</li>
<br>
<button @click="Add">在最前方添加一个用户</button>
</ul>
在输入框中输入与之前相同的内容,点击按钮后这次的页面则变成了下图

很明显,这次就对了!
三、原因分析
为什么用id和index作为key出来的效果天差地别呢,首先来分析一下key的作用原理。
用index作为key时:

首先会根据初始数据生成虚拟DOM,然后将虚拟DOM转为真实DOM,在加入新数据以后,再根据新数据生成新的虚拟DOM,此时Vue并不会再重新将新虚拟DOM直接转为真实DOM,而是进行一个虚拟DOM的对比算法。如下:

首先在新的虚拟DOM中按照顺序取出第一项,然后根据标识“key=0”在旧的虚拟DOM中寻找拥有一样“key=0”的节点,然后开始挨个对比。

第一个节点为文本节点,Vue发现一个为张三一个为赵六,不一致,于是将新的文本节点赵六转为真实DOM

然后来到第二个标签节点input,需要注意的是,我们对文本框的输入是在真实DOM中操作的,但在虚拟DOM中两边的标签节点input是一样的,所以这时候Vue不会将它重新转成真实DOM,而是直接复用左边的。

以此类推,key等于1和等于2时,文本节点重新转为真实DOM,标签节点复用。

当来到key等于3这一项时,发现左边并没有key是等于3的一项,所以这个时候,Vue直接将右边key等于3这一项直接转为真实DOM。
用id作为key时:

首先也是按照顺序取出第一项,然后根据标识“key=04”在左边寻找拥有同样key的一项,发现没有,于是直接转为真实DOM。

然后按顺序取出第二项,根据标识“key=01”,在左边寻找也是“key=01”的一项,挨个对比文本节点和标签节点,发现两个节点都完全一样,所以直接复用之前的真实DOM。

以此类推,李四和王五都是直接复用左边的真实DOM。
四、总结
- 用index作为key可能会引发的问题:若对数据进行逆序添加、逆序删除等破坏顺序的操作时,会产生没有必要的真实DOM更新,此时界面效果没有问题,但效率太低。
- 在开发中如何选择key:最好使用每条数据的唯一标识作为key,比如id、身份证号、手机号等,如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。
v-for中key的作用与原理的更多相关文章
- vue中:key 和react 中key={} 的作用,以及ref的特性?
vue中:key 和react 中key={} 为了给 vue 或者react 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性 一句话概括就是 ...
- vue中key的作用 v-for里警告 v-if的复用
vue总是会复用页面上已经存在的dom,区别的方法是加上key就可以,还设有v-for时候的警告也是如此key的作用是区别这条跟那条的.<body> <div id="ap ...
- vue中key的作用
1.v-if中用key管理可复用的元素 Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染.这么做,除了使 Vue 变得非常快之外,还有一些有用的好处.例如,如果你允许用户在不同的 ...
- @Transacitonal注解不生效之spring中expose-proxy的作用与原理
几年前记得整理过,@Transacitonal注解的方法被另外一个方法调用的时候,事务是不生效的. 如果大量代码已经这么写了,这个时候抽取出去不现实,怎么办呢? 答案就是在<aop:aspect ...
- Vue2.0 v-for 中 :key 的作用
- Vue学习之--------列表渲染、v-for中key的原理、列表过滤的实现(2022/7/13)
文章目录 1.基本列表 1.1 基本知识 1.2 代码实例 1.3 测试效果 2.key的原理 2.1基本知识 2.2 代码实例 2.3 测试效果 2.4 原理图解 3.列表过滤 3.1 代码实例 3 ...
- 【react】---react中key值的作用
一.React中key值得作用 react中的key属性,它是一个特殊的属性,它是出现不是给开发者用的,而是给React自己使用,有了key属性后,就可以与组件建立了一种对应关系,简单说,react利 ...
- react中key的使用
面试题: 1). react/vue中的key的作用/内部原理 2). 为什么列表的key尽量不要用index 虚拟DOM的key的作用? 1). 简单的说: key是虚拟DOM对象的标识, 在更新显 ...
- 图解vue中 v-for 的 :key 的作用,虚拟dom Diff算法
其实不只是vue,react中在执行列表渲染时也会要求给每个组件添加上key这个属性. 要解释key的作用,不得不先介绍一下虚拟DOM的Diff算法了. 我们知道,vue和react都实现了一套虚拟D ...
随机推荐
- Word 脚注和尾注是什么?怎么设置?
描述 脚注一般位于页面的底部,作为文档某处内容的注释.尾注一般位于文档的末尾,列出引文的出处等. 设置脚注和尾注 将光标移动到要插入脚注或尾注的地方,然后点击"引用"选项卡. 左边 ...
- Jira使用浅谈篇一
本篇参考: https://www.jianshu.com/u/9dd427d9ad94 Salesforce 生命周期管理(二)Agile & Scrum 浅谈 我们都知道 salesfor ...
- P4035 [JSOI2008]球形空间产生器 (向量,高斯消元)
题面 有一个 n n n 维球,给定 n + 1 n+1 n+1 个在球面上的点,求球心坐标. n ≤ 10 n\leq 10 n≤10 . 题解 好久以前的题了,昨天首 A . n n n 太小了! ...
- [HDU3976]Electric resistance(电阻)(信竞&物竞)(高斯消元)
题面 Problem Description Now give you a circuit who has n nodes (marked from 1 to n) , please tell abc ...
- HTTP2指纹识别(一种相对不为人知的网络指纹识别方法)
这是关于网络指纹识别的两部分系列的第二部分 上一部分我介绍了有关TLS 指纹识别方法(以及在不同客户端的指纹有何区别): https://mp.weixin.qq.com/s/BvotXrFXwYvG ...
- Linux_ps总结
ps命令用于监测进程的工作情况.进程是一直处于动态变化中,而ps命令所显示的进程工作状态时瞬间的 使用方式: ps [options] 常用参数 -A 显示所有进程 -a 显示现行终端机下的所有进程, ...
- 【读书笔记】C#高级编程 第十九章 程序集
(一)程序集的含义 程序集是.NET用于部署和配置单元的术语. .NET应用程序包含一个或多个程序集.通常扩展名是EXE或DLL的.NET可执行程序称为程序集. 程序集是自我描述的安装单元,由一个或多 ...
- Netty 学习(二):服务端与客户端通信
Netty 学习(二):服务端与客户端通信 作者: Grey 原文地址: 博客园:Netty 学习(二):服务端与客户端通信 CSDN:Netty 学习(二):服务端与客户端通信 说明 Netty 中 ...
- 在没有安装终端服务的Windows 2012 R2服务器上配置远程桌面的属性
在没有安装终端服务的Windows2012 R2服务器上配置远程桌面的属性. 从Windows 2012开始,如果没有在服务器上启用终端服务的计算机,要想配置远程桌面使用更安全加密的RDP连接就 ...
- Flink基础概念入门
Flink 概述 什么是 Flink Apache Apache Flink 是一个开源的流处理框架,应用于分布式.高性能.高可用的数据流应用程序.可以处理有限数据流和无限数据,即能够处理有边界和无边 ...