【Vue中key的原理】
在Vue中,以key为对比算法标识,在数据修改或更新后,通过key这个唯一标识进行对比虚拟DOM,从而决定节点的重新加载以及复用。
Vue中key的原理
key就是对节点进行一个标识。
在Vue中,以key为对比算法标识,在数据修改或更新后,通过key这个唯一标识进行对比虚拟DOM,从而决定节点的重新加载以及复用。
虚拟DOM
虚拟DOM 本质上是一个js对象 ,通过对象来表示真实的DOM结构。
key是虚拟DOM对象的标识,当状态中的数据发生变化时,Vue会根据 新数据
生成 新的虚拟DOM
实例展示
现在,我们通过一个问题来展开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=\, initial-scale=1.0">
<title>Document</title>
<!-- 引入Vue.js -->
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<!-- 此时按钮只能点击一次 -->
<button @click.once="add">添加人员(小明)</button>
<!-- 遍历数组 -->
<h2>人员列表(遍历数组)</h2>
<ul>
<li v-for="(p, index) in presons" :key="index">
姓名:{{p.name}}-- 年龄{{p.age}}--
备注:<input type="text">
</li>
</ul>
</div>
</body>
<script>
Vue.config.productionTip = false;
const vm = new Vue({
el:'#app',
data:{
presons:[
{id:'001', name:'张三', age:18},
{id:'002', name:'李四', age:21},
{id:'003', name:'王五', age:19},
]
},
methods: {
add(){
// 只有往前添加数据,才能看出问题
const preson = {id:'004', name:'小明', age:12};
this.presons.unshift(preson);
}
},
})
</script>
</html>
在列表渲染中,使用的是index作为key
,并没有选择data中的preson.id作为key
点击按钮添加人员信息:
为了能引出key的原理以及作用,再次我通过一个问题引出,假如每一个人的备注项输入框都输入上内容,然后再添加一个人员,就会存在以下问题
每个人的备注输入框都输入内容:
点击按钮添加人员信息:
此时我们会发现,当点击按钮添加信息后,备注项输入框内容发生了错误,添加人员后,备注项内容并没有跟随对应的节点,为什么出现这种情况呢,其实问题所在就是因为我们选用了index作为key
,假如我们选用persons.id作为key
,则不会出现此情况
使用persons.id作为key:
点击按钮添加人员信息:
那为什么选用index作为key?
在Vue中,存在虚拟DOM和对比算法,而对比算法的开展需要唯一标识作为对比前提,当我们选用index作为唯一标识时,其实Vue默认可以看做index是为下标索引,也就是说从0~n。和数组索引一样,当我们往节点第一位添加或更新数据时,其实新添加的数据索引为0,原有数据依次往后挪一位,这就导致在对比的时候,会出现原有信息错乱
在数据更新过后,新旧虚拟DOM会运用对比算法进行对比,而对比的前提就是key这个唯一标识符,通过key对比前后数据的变化,如果对比之后不一致的内容就不能复用, 只能把新的虚拟DOM转化为新的节点,当数据无改动时,则复用之前数据,然后再转化为真实DOM,也就是呈现在页面的内容。
虚拟DOM对比算法
Vue进行 新虚拟DOM 与 旧虚拟DOM 的差异比较,比较规则如下:
-
旧虚拟DOM中找到了与新虚拟DOM相同的key:
若虚拟DOM中内容没变,直接使用之前的真是DOM 若虚拟DOM中的内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM
-
旧虚拟DOM中未找到与新虚拟DOM相同的key:
创建新的真实DOM,随后渲染到页面
用index作为key可能会引发的问题
-
若对数据进行:逆序添加、逆序删除等破坏顺序的操作:
会产生没有必要的真实DOM的更新 ==> 界面效果没什么问题,但是效率低
-
如果结构中还包括输入类的DOM:
会产生错误的DOM更新 ==> 界面有问题
开发中如何选择key?
最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值
如果不存在对数据的逆序添加,逆序删除等破坏顺序的操作,仅用于渲染列表用于展示, 使用index作为key是没有问题的。
总结
在Vue中,key的存在其作用就是在虚拟DOM转换为真实DOM这个过程中虚拟DOM新旧对比的前提,当然可以选择不同的唯一值来充当key,但是,无论在何种条件下,一定要考虑清除key唯一标识符,否则在虚拟DOM对比时,将出现错误,以至于导致页面呈现的内容出错,虚拟DOM就是为了解决浏览器性能问题而被设计出来的。而key的存在,又为虚拟DOM比较时,提高了一定量的效率和节省了一定量的内存。
创作不易,记得点赞收藏,关注博主不迷路哟~~
更多推荐
所有评论(0)