什么是Virtual DOM
- Virtual DOM(虚拟DOM),是由普通的JS对象来描述DOM对象
真实DOM成员,如下代码打印结果会发现真实的DOM代码非常庞大
// 真实DOM对象
let element = document.querySelector('#app')
let s = ''
for (var key in element) {
s += key + ','
}
console.log(s)
使用Virtual DOM来描述真实DOM
// 虚拟DOM
{
sel: 'div',
data: {},
children: undefined,
text: 'Hello Virtual DOM',
elm: undefined,
key: undefined
}
为什么要使用Virtual DOM
前端开发刀耕火种的时代
- MVVM框架解决视图和状态同步问题
- 模板引擎可以简化视图操作,没办法跟踪状态
- 虚拟DOM跟踪状态变化
参考github上virtual-dom的动机描述
维护视图和状态的关系
- 复杂视图情况下提升渲染性能
跨平台
-
- Vue.js 2.x内部使用的虚拟DOM就是改造的Snabbdom
- 大约200SLOC(single line of code)
- 通过模块可扩展
- 源码使用TypeScript开发
- 最快的Virtual DOM之一
- virtual-dom
}
- 目录结构
模块
- 模块的作用
- Snabbdom的核心库并不能处理DOM元素的属性/样式/事件等,可以通过注册Snabbdom默认提供的模块来实现
- Snabbdom中的模块可以用来扩展Snabbdom的功能
- Snabbdom中的模块的实现是通过注册全局的钩子函数来实现的
官方提供的模块
attributes
- 设置 DOM 元素的属性,使用
setAttribute ()
- 处理布尔类型的属性
props
- 和 attributes 模块相似,设置 DOM 元素的属性
element[attr] = value
- 不处理布尔类型的属性
class
- 切换类样式
- 注意:给元素设置类样式是通过
sel
选择器dataset
- 设置
data-*
的自定义属性eventlisteners
- 注册和移除事件
style
- 设置行内样式,支持动画
- delayed/remove/destroy
模块的使用步骤
- 导入需要的模块
- init()中注册模块
- h()函数的第二个参数处使用模块
src目录
│ h.ts h() 函数,用来创建 VNode
│ hooks.ts 所有钩子函数的定义
│ htmldomapi.ts 对 DOM API 的包装
│ is.ts 判断数组和原始值的函数
│ jsx-global.d.ts jsx 的类型声明文件
│ jsx.ts 处理 jsx
│ snabbdom.bundle.ts 入口,已经注册了模块
│ snabbdom.ts 初始化,返回 init/h/thunk
│ thunk.ts 优化处理,对复杂视图不可变值得优化
│ tovnode.ts DOM 转换成 VNode
│ vnode.ts 虚拟节点定义
│
├─helpers
│ attachto.ts 定义了 vnode.ts 中 AttachData 的数据结构
│
└─modules 所有模块定义
attributes.ts
class.ts
dataset.ts
eventlisteners.ts
hero.ts example 中使用到的自定义钩子
module.ts 定义了模块中用到的钩子函数
props.ts
style.ts
Snabbdom文档
- 看文档的意义
- 学习任何一个库都要先看文档
- 通过文档了解库的作用
- 看文档中提供的示例,自己快速实现一个demo
- Snabbdom文档
- https://github.com/snabbdom/snabbdom
- (稍后)使用的版本v2.1.0