diff算法:两个虚拟DOM如何进行差异化比较
diff算法心得:
-
最小量更新,关键在key,key是这个节点唯一标识,告诉diff算法,在更改前后它们是同一个节点
- 只有同一个虚拟节点(选择器相同且key相同),才能进行精细化比较
-
只进行同层比较,不会进行跨层比较
1.最小量更新,关键在key,是这个节点唯一标识,告诉diff算法,在更改前后它们是同一个节点
需求:点击按钮时,myVnode1转变myVnode2
import {
init,
classModule,
propsModule,
styleModule,
eventListenersModule,
h
} from "snabbdom";
// 创建出patch函数(diff算法的核心函数)
const patch =init([classModule,propsModule,styleModule,eventListenersModule,])
// h函数创建虚拟节点myVnode1
const myVnode1 =h('ul',[
h('li',{key:'1'},'1'),
h('li',{key:'2'},'2'),
h('li',{key:'3'},'3'),
h('li',{key:'4'},'4'),
])
// h函数创建虚拟节点myVnode2
const myVnode2 =h('ul',[
h('li',{key:'1'},'1'),
h('li',{key:'2'},'2'),
h('li',{key:'5'},'5'),
h('li',{key:'3'},'3'),
h('li',{key:'4'},'4'),
])
// 让虚拟节点上树(显示在页面上)
const container =document.getElementById('container')
const btn =document.getElementById('btn')
patch(container,myVnode1)
//点击按钮时,myVnode1转变myVnode2
btn.onclick=()=>{
patch(myVnode1,myVnode2)
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn">按我改变DOM</button>
<div id="container"></div>
<script src="/xuni/bundle.js"></script>
</body>
</html>
点击按钮后
2.只有同一个虚拟节点(选择器相同且key相同),才能进行精细化比较
需求:如选择器不相同时且key相同,则会不在同一个虚拟节点,就会暴力删除旧的并插入新的
import {
init,
classModule,
propsModule,
styleModule,
eventListenersModule,
h
} from "snabbdom";
// 创建出patch函数(diff算法的核心函数)
const patch =init([classModule,propsModule,styleModule,eventListenersModule,])
// h函数创建虚拟节点myVnode1
const myVnode1 =h('ul',[
h('li',{key:'A'},'A'),
h('li',{key:'B'},'B'),
h('li',{key:'C'},'C'),
h('li',{key:'D'},'D'),
])
// h函数创建虚拟节点myVnode2
const myVnode2 =h('ol',[
h('li',{key:'A'},'A'),
h('li',{key:'B'},'B'),
h('li',{key:'C'},'C'),
h('li',{key:'D'},'D'),
])
// 二.让虚拟节点上树(显示在页面上)
const container =document.getElementById('container')
const btn =document.getElementById('btn')
patch(container,myVnode1)
//点击按钮时,myVnode1转变myVnode2
btn.onclick=()=>{
patch(myVnode1,myVnode2)
}
3.只进行同层比较,不会进行跨层比较
需求:跨层比较了,不会最小量更新(精细化比较),而是就会暴力删除旧的并插入新的
// h函数创建虚拟节点myVnode1
const myVnode1 =h('div',[
h('p',{key:'A'},'A'),
h('p',{key:'B'},'B'),
h('p',{key:'C'},'C'),
h('p',{key:'D'},'D'),
])
// h函数创建虚拟节点myVnode2
const myVnode2 =h('div',h('section',{},[
h('p',{key:'A'},'A'),
h('p',{key:'B'},'B'),
h('p',{key:'C'},'C'),
h('p',{key:'D'},'D'),
]))