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 ...
随机推荐
- Jira使用浅谈篇一
本篇参考: https://www.jianshu.com/u/9dd427d9ad94 Salesforce 生命周期管理(二)Agile & Scrum 浅谈 我们都知道 salesfor ...
- 2-2 selenium IDE自动化实战
Selenium IDE 自动化实战 任务1: 自动在百度搜索"我要自学网" 然后在搜索结果页面点击进入自学网主页 任务2 实现自学网自动登录个人账号 Test2017 12345 ...
- sftp服务器的搭建与连接
在个人租用的vps上搭建sftp服务器并通过本机连接上去 本实验所需:Xshell(xshell中包含xftp).一台vps(windows系统) sftp是一种协议,即SSH File Transf ...
- 第九十七篇:CSS的选择器及优先级
好家伙,来补一点关于CSS的基础 1.id选择器 id 选择器可以为标有特定 id 的 HTML 元素指定特定的样式 使用#号来定义样式 2.class选择器 class 选择器用于描述一组元素的样式 ...
- docker容器资源限制:限制容器对内存/CPU的访问
目录 一.系统环境 二.前言 三.docker对于CPU和内存的限制 3.1 限制容器对内存的访问 3.2 限制容器对CPU的访问 一.系统环境 服务器版本 docker软件版本 CPU架构 Cent ...
- mybatis 输出sql日志
logging.level.com.dsmp.server.core.pgsqldao=debug com.dsmp.server.core.pgsqldao 为包名
- 【读书笔记】C#高级编程 第二章 核心C#
(一)第一个C#程序 创建一个控制台应用程序,然后输入代码,输入完毕后点击F5 Console.WriteLine();这条语句的意思:把括号内的内容输出到界面上: Console.ReadKey() ...
- 一个包搞定中文数据集: datasetstore
工作中,总是要使用各种中文数据集,每次使用数据集都要花费不少的时间进行寻找,写预处理代码,结合不同的模型和框架做出相应的处理.有的时候好不容易找到合适的数据集,但是却因为网络问题,无法下载,下载了很长 ...
- linux 运维有趣的实用工具
1.实时监控磁盘 IO-IOTop IOTop 命令是专门显示硬盘 IO 的命令, 界面风格类似 top 命令. [root@localhost ~]# yum -y install iotop` 2 ...
- AVL tree 高度上下界推导
1. 最大高度对应 Node 数量 \(N_{h}\) 的递归公式 设有一棵 AVL tree 的高度为 \(h\), 对于该树, 构成该树的最少 node 数量为 \(N_{h}\) . 有: 最坏 ...