snabbdom
snabbdom是著名的虚拟DOM库,是diff算法的鼻祖,Vue源码借鉴了snabbdom
测试环境搭建
- 搭建webpack和webpack-dev-server开发环境
- 需按照最新版webpack@5:npm i -D webpack@5 webpack-cli@3 webpack-dev-server@3
- 配置webpack.config.js文件
const path = require('path');
module.exports = {
//入口
entry: './src/index.js',
//出口
output: {
publicPath: 'virtual',
filename: 'bundle.js'
},
devServer: {
port: 8080,
contentBase: 'www'
}
}
虚拟dom
用JavaScript对象描述dom的层次结构,dom中一切属性都在虚拟dom中有对应属性
新虚拟dom和老虚拟dom进行diff(精细化比较),算出应该如何最小量更新,最后反映到真正的dom上
snabbdom的h函数
-
作用:h函数用来产生虚拟节点(vnode)
-
虚拟节点属性
- children:子元素,默认undefined
- data:属性、样式,默认{}
- elm:对应的真实dom是否上树
- key:唯一标识
- sel:选择器
- text:文本
-
创建虚拟节点
var myVNode = h('a', {
props: {
href: 'http://www.baidu.com',
target: '_blank'
}
}, 'hello world');
//嵌套使用
var myMultiVNode = h('ul',{},[
h('li',{},'1'),
h('li',{},'2'),
h('li',{},'3')
])
手写h函数
- 根据源码的TS版代码,仿写JS代码
- 编写低配版h函数,接收三个参数,调用形态可以如下:
- h(‘sel’,{},‘text’)
- h(‘sel’,{},[])
- h(‘sel’,{},h())
diff算法原理
手写diff算法
- 手写patch函数
- 新旧节点不同时,删除旧的,调用createElement创建新的
- 新旧节点相同时,精细化比较
- 手写新旧节点text的不同情况
- diff更新子节点
- 手写createElement函数