var data={
arr:[]
}
var vDom = {
tag:"div",
attr:{
id:"content"
},
children:[
{tag:"p",content:2},
{tag:"ul",attrs:{className:"list-group"}}
]
}
//修改data里面的数据
data.arr.push("111111 ")
data.arr.push("222222 ")
var newDom = {
tag:"div",
attr:{
id:"content"
},
children:[
{tag:"p",content:2},
{tag:"ul",attrs:{className:"list-group"},children:[
{tag:"li",content:"11111"},
{tag:"li",content:"22222"}
]}
]
}
在虚拟DOM中,DOM的状态发生变化时,虚拟DOM会进行Diff运算,来更新只需要被替换的DOM,而不是全部重绘。
在Diff算法中,只平层的比较前后两棵DOM树的节点,没有进行深度的遍历。
如果想在中间插入节点F,简单粗暴的做法就是:卸载C,装载F,卸载D,装载C,卸载E,装载D,装载E。(通俗的来说就是,我们在购买火车票的时候,有人插队在我们面前,我们只能往后退一个位置,依次占用后面买票者的位置。)如下图:
写代码时,如果没有给数组或者枚举类型定义一个key,就会采用上面的简单粗暴做法。
如果给元素增加key后,Vue就能根据key,直接找到具体的位置进行操作,效率比较高。(就像我们购买电影票看电影,每张电影票上面都有对应的座位号,我们到电影院之后,只需要按照电影票上的座位号入座即可)如下图:
v-for中的key属性,一方面可以提高性能,另一方面还可以避免出错。
参考:
虚拟dom与key的关系
虚拟DOM的框架/工具操作流程具体代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
//DOM节点在HTML文档中的表现形式
<div id="content">
<p>{{ 1+1}}</p>
<ul class="list-group">
</ul>
</div>
<script src="./base/vue.js"></script>
<script>
var data = {
arr:[]
}
//1.内存中生成一棵虚拟dom树
//用js代码表示DOM节点的伪代码
var vDom = {
tag:"div",
attr:{
id:"content"
},
children:[
{tag:"p",content:2},
{tag:"ul",attrs:{className:"list-group"}}
]
}
//2.将内存中的虚拟dom树初始化渲染成真实dom树
//3.更新虚拟DOM中data里面的数据
data.arr.push("111111 ")
data.arr.push("222222 ")
//4.将之前的虚拟dom树结合新的数据生成一棵新的虚拟dom树
var newDom = {
tag:"div",
attr:{
id:"content"
},
children:[
{tag:"p",content:2},
{tag:"ul",attrs:{className:"list-group"},children:[
{tag:"li",content:"11111"},
{tag:"li",content:"22222"}
]}
]
}
//5.将此次生成的新的虚拟dom树与上一次的虚拟dom树结构进行对比,对比差异(diff算法)
//6.将对比出来的差异的部分进行重新真实dom结构的渲染