1、什么是虚拟DOM?
虚拟DOM是使用普通JavaScript对象描述真实DOM,本质就是Js对象。
Vue.js中的虚拟DOM借鉴了Snabbdom,并添加了Vue.js属性
2、为什么使用虚拟DOM?
1、避免直接操作DOM,提高开发效率
2、虚拟DOM在复杂视图下可以提高渲染性能。住:首次渲染,会增加开销
3、Snabbdom几个重要函数
1、h函数
- 创建JS对象来描述dom节点,即创建VNode对象
// 创建vnode
let vnode = h('h1#title','我是title')
//渲染成节点后为:
<h1 id="title">我是title</h1>
- 例如: Vue中的h函数
new Vue({
router,
render: h => h(App)
}).$mount('#app')
说明: 方法的重载,h函数可以有多个参数,传递不同的参数代表不同的功能,传递相同的参数但是不同的参数类型也代表着不同的执行方法
查看snabbdom的源码可以看到,h函数,有4个重载函数,
注意,h函数还有一个特殊的用法,h('!')
渲染出来是注释信息<!-- -->
查看源码,可以看到,vnode的格式为:
2、init函数
返回patch函数,参数为数组,数组内部放置模块信息,例如: styleModule
(添加样式模块),eventListenersModule
(添加事件模块),当什么都不传递的时候,创建的patch
函数,仅可以创建dom节点,但是不能添加样式及事件
查看snabbdom源码可以看到,包括以下几个模块
import { init, h, styleModule, eventListenersModule } from 'snabbdom'
// 1、创建patch函数
// const patch = init([])
const patch = init([styleModule, eventListenersModule])
// 2、创建具有样式信息及点击事件的vnode
let vnode = h(
'div#container',
{
style: {
backgroundColor: 'red',
width: '100px',
height: '100px'
},
on: {
click(){
console.log('123')
}
}
},
[h('h1#title', { style: { color: '#fff' } }, '我是title')]
)
let dom = document.getElementById('app')
// 3、使用patch函数将vnode渲染到dom元素中
patch(dom, vnode)
3、patch整体过程分析
- patch(oldVnode, newVnode)
- 把新节点中变化的内容渲染到真是DOM,最后返回新节点作为下一次处理的旧节点
- 对比新旧VNode是否相同节点(节点的key和sel是否相同)
- 如果不是相同节点,删除之前的内容,重现渲染
- 如果是相同节点,再判断新的VNode是否有text,如果有并且和oldVnode的text不同,直接更新文本内容
- 如果新的VNode有children,判断子节点是否有变化
4、体验Snabbdom
1、创建新项目,npm init -y
创建package.json
2、安装parcel cnpm install parcel-bundler -D
3、安装Snabbdom cnpm install snabbdom@2.1.0
4、修改package.json中的script
"scripts": {
"dev": "parcel index.html --open",
"build": "parcel build index.html"
},
5、创建basicusage.js
// basicusage.js
import { init } from 'snabbdom/build/package/init'
import { h } from 'snabbdom/build/package/h'
// 1、导入模块
import { styleModule } from 'snabbdom/build/package/modules/style'
import { eventListenersModule } from 'snabbdom/build/package/modules/eventlisteners'
// 2、注册模块
const patch = init([styleModule, eventListenersModule])
// 3、使用h函数的第二个参数传入模块中使用的数据(对象)
let vnode = h('div', [
h('h1', { style: { backgroundColor: 'pink' } }, 'Hello world'),
h('button', { on: { click: eventHandler } }, 'Hello p')
])
function eventHandler() {
console.log("点击了")
}
let app = document.querySelector("#app")
patch(app, vnode)
6、创建index.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>Snabbdom-demo</title>
</head>
<body>
<div id="app">
</div>
<script src="./src/basicusage.js"></script>
</body>
</html>
7、执行npm run dev
至此完成使用Snabbdom进行虚拟dom转化渲染完成。