虚拟DOM
虚拟DOM的解决方式是通过状态生成一个虚拟节点树,然后使用虚拟节点树进行渲染。在渲染之前会使用新的虚拟节点树和上一次生成的虚拟节点树进行对比,只渲染不同的部分。
案例:感受虚拟DOM的好处
snabbdom的官方文档GitHub
snabbdom的CDN链接
index.html
<!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>虚拟DOM的好处</title>
</head>
<body>
<h1>虚拟DOM的好处</h1>
<ul id="list">
</ul>
<button id="btn">改变</button>
</body>
<script crossorigin="anonymous" integrity="sha384-pXMwIxxyUHLJJzC3cojA57byB8F8NHhFzg7+ji2422hLmE2RqlWX6R8YrSSntkte"
src="https://lib.baomitu.com/snabbdom/0.7.4/h.js"></script>
<script crossorigin="anonymous" integrity="sha384-7IXyrLPuMtVMYZkX7xfMcGwR1HG0Qb5P9bWm5mCoF3XEKwH3yRPSyaNex9PdxlOd"
src="https://lib.baomitu.com/snabbdom/0.7.4/snabbdom-class.js"></script>
<script crossorigin="anonymous" integrity="sha384-kzNaK5pakSWoKrTaqDckuoljrV2j7cPLMVZkB1f7tYjN+eM4Gn2d8aeBPHXeHqSv"
src="https://lib.baomitu.com/snabbdom/0.7.4/snabbdom-eventlisteners.js"></script>
<script crossorigin="anonymous" integrity="sha384-bzaUIRwEVAGY6ZjnrthKwZAv/Ho7XzGCx6p/BFI24WTYe1WIlCfBwHbRXSGz11TI"
src="https://lib.baomitu.com/snabbdom/0.7.4/snabbdom-patch.js"></script>
<script crossorigin="anonymous" integrity="sha384-8gDjDJzxvqg1FA1Y9AgdFo7r0B7jeYuwH+r8ryk7m9izeCCLJth22F5Rk17Gc7ze"
src="https://lib.baomitu.com/snabbdom/0.7.4/snabbdom-style.js"></script>
<script crossorigin="anonymous" integrity="sha384-ybU1RWuEDBxPZeDSr2SKw8fS74Z4jRCAQvbNjzwJ5+2bpo5BZUMc6nDRB3VkxgUo"
src="https://lib.baomitu.com/snabbdom/0.7.4/snabbdom.js"></script>
<script crossorigin="anonymous" integrity="sha384-it5PCvgPblZcvejIFSyijWkqopZkZwgT/fc6UByqoGk0T38LjqxKjr2rh8aMHMIu"
src="https://lib.baomitu.com/snabbdom/0.7.4/tovnode.js"></script>
<script crossorigin="anonymous" integrity="sha384-8aqZdA5zmzx40JNH2n2f8erDmLgixmeGY8mYamFnkNafIlcUfrcgGVISgBO+3+OF"
src="https://lib.baomitu.com/snabbdom/0.7.4/snabbdom-props.js"></script>
<script src="./index.js"></script>
</html>
inde.js
//引入snabbdom库
const snabbdom = window.snabbdom
//将 vnode(虚拟节点)塞入空的容器中
const patch = snabbdom.init([
snabbdom_class,
snabbdom_props,
snabbdom_style,
snabbdom_eventlisteners
])
//创建vnode
const h = snabbdom.h
//空的容器
const container = document.getElementById('list')
//获取按钮节点
const btn = document.getElementById('btn')
//创建vnode虚拟的节点
const vnode = snabbdom.h('ul#list', {
}, [
h('li.item', {
}, '第一项'),
h('li.item', {
}, '第二项')
])
//vnode -> 容器
patch(container, vnode);
//
btn.addEventListener('click', () => {
const new_vnode = snabbdom.h('ul#list', {
}, [
h('li.item', {
}, '第一项'),
h('li.item', {
}, '关注我'),
h('li.item', {
}, '第三项')
])
patch(vnode, new_vnode)
vnode = new_vnode
})
VNode
Vue.js存在一个VNode类,使用它可以实例化不同类型的vnode实例,而不同类型的vnode实例各自表示不同类型的DOM元素
VNode类型
diff算法
Patch
虚拟DOM核心就是patch,它可以将vnode渲染称真实的DOM
实际上是用JavaScript运算成本来换取DOM的成本,JavaScript运算速度是比DOM快的多的
整个patch过程并不复杂。当oldValue不存在时,直接使用vnode渲染视图;当oldVnode和vnode都存在但并不是同一个节点时,使用vnode创建的DOM替换旧的DOM元素;当oldValue和vnode是同一个节点时,使用更详细的对比操作对真实的DOM节点进行更新。
资料
1.《深入浅出Vue.js》这本书很不错
2.视频讲解