Vue中key的作用(从虚拟DOM说起),为什么不能用index值当作key
Vue中key的作用(从虚拟DOM的原理说起),为什么不能用index值当作key
本文会带着大家过一遍Vue中的key有什么作用,以及key的值为什么不可以用index
我们时候会用到key
相信大家在最开始学习Vue的时候,大概是在学习v-for这个指令的时候接触到key的,我用代码带着大家复现一遍
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="root">
<button @click="add">添加一个老刘</button>
<hr>
<ul>
<li v-for="(p,index) of persons">
{{ p.name }}-{{ p.age }}
<input type="text">
</li>
</ul>
</div>
<script>
Vue.config.productionTip = false
new Vue({
el: '#root',
data: {
persons: [
{ id: 1, name: '张三', age: 18 },
{ id: 2, name: '李四', age: 19 },
{ id: 3, name: '王五', age: 20 },
]
},
methods: {
add() {
const p = { id: 4, name: '老刘', age: 21 }
this.persons.unshift(p)
}
},
})
</script>
</body>
</html>
按照以上代码,我们得到了浏览器所显示的内容,但是在这里,大家会发现,我并没有加key这个属性,这是因为:
如果不添加key属性,则系统默认给我们加了一个key,而且它的默认值是index
也就是说
<li v-for="(p,index) of persons">
等于
<li v-for="(p,index) of persons" :key="index">
这点我就说到这里了
好,我们现在知道了key在什么时候出现,啊,是在列表渲染的时候出现
但是我们还是不知道这个key到底是干什么的
虚拟DOM
我们在知道key的作用之前,首先要知道Vue的一个特性
使用虚拟DOM和Diff算法,尽量复用DOM节点
我不知道大家到底清不清楚这个虚拟DOM(VDOM)是什么,这里我简单带着大家复习一下
我们先要知道,我们在原生JS里面去写一个人员列表的时候,我们是怎么写的
我们是这样去写的,但是我们发没发现一个问题,如果我们想在这个列表里面添加一个新的数据呢,我们需要遍历一遍,看看有没有相同的元素,然后再插进去,是不是挺麻烦的
于是,在Vue中,我们有了一个新的概念,虚拟DOM
我们第一遍添加数据的时候,Vue会把我们添加数据放入到一个虚拟DOM中,然后在我们添加新的数据的时候,会产生新的虚拟DOM,关键来了
我们新的虚拟DOM会和旧的虚拟DOM进行一个比较,看看有没有什么不同(different)简称Diff算法,发现新的虚拟DOM中有跟旧虚拟DOM中有相同的内容,那么,我们就会直接调用旧的虚拟DOM中的内容(也就是复用),从而提高效率
好了,这个就带着大家复习到这里,我们还是进入正题
key的作用
我们新虚拟DOM在跟旧的虚拟DOM进行对比的时候,是根据key值的序号,逐个进行对比的
key为1的新虚拟DOM去找key为1的旧的虚拟DOM,看看内容是不是一样,如果一样,就直接复用,如果不一样,就修改为新的内容,或者添加新的内容
不知道大家有没有懂,这里带着大家用个常见的反例,带着大家感受一下,就是为什么不能用index(索引值)用来当作key值
index做key值为什么不行
我们直接点击按钮,添加,ok,没有看出什么问题
但是,如果初始的文本框里是有内容的呢?
我们再点击添加按钮试试
发现问题了吗,是不是串了
这是为什么呢?
我们就拿张三举例,它最开始的索引值是不是0,但是在头部添加了一个新的元素之后,它的索引值是不是就变成1了,依次,是不是原本的内容,索引值都变化了,这就导致了一个关键的问题,key值变了
然后我们虚拟DOM还是根据key值进行diff算法的,是不是这下就完犊子了,全变了,不能怪我VDOM瞎,是这index太完蛋,它变啥
这样,是不是我们就知道为什么不能用index值来当作key值了
因为index的值是变化的
这样也引出了一个重要的概念,我们的key值,需要一个固定不变的值,就类似于我们的身份证号一样,需要值与元素一一对应,要唯一
当然哈,有的小伙伴会问,那为啥是id呢,不可以是别的呢
这随意啊!只要是固定的值,就可以,只不过我们习惯于id了,我们在数据链接MySQL的值,一般后端都会自动给我们生成,都是做好了的,他给我们什么名字,我们就用什么名字,给的名字为id,我们就用id,给我们hhh,我们就要hhh
总结
面试题:react、vue中的key有什么作用?(key的内部原理)
-
虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,
随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下: -
对比规则:
(1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
①.若虚拟DOM中内容没变, 直接使用之前的真实DOM!
②.若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
(2).旧虚拟DOM中未找到与新虚拟DOM相同的key
创建新的真实DOM,随后渲染到到页面。 -
用index作为key可能会引发的问题:
1.若对数据进行:逆序添加、逆序删除等破坏顺序操作:
会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。 -
如果结构中还包含输入类的DOM:
会产生错误DOM更新 ==> 界面有问题。 -
开发中如何选择key?:
1.最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,
使用index作为key是没有问题的。
OK,结束了,感谢观看,有问题就问
更多推荐
所有评论(0)