Virtual DOM
什么是Virtual DOM
- Virtual DOM(虚拟DOM),是由普通的JS对象来描述DOM对象,因为不是真实的DOM对象,所以叫Virtual DOM
为什么使用Virtual DOM
- 手动操作DOM比较麻烦,还需要考虑浏览器兼容性问题,虽然有jquery等库简化DOM操作,但是随着项目的复杂DOM操作复杂提升
- 为了简化DOM的复杂操作于是出现了MVVM框架,MVVM框架解决了视图和状态的同步问题
- 为了简化视图的操作我们可以使用模板引擎,但是模板引擎没有解决跟踪状态变化的问题,于是Virtual DOM出现了
- Virtual DOM的好处是当状态改变时不需要立即更新DOM,只需要创建一个虚拟树来描述DOM, Virtual DOM内部将弄清除如何有效(diff)的更新DOM
- 虚拟DOM可以维护程序的状态,跟踪上一次的状态,通过比较前后两次状态的差异更新真实DOM
虚拟DOM的作用
- 维护视图和状态的关系
- 复杂视图情况下提升渲染性能
- 除了渲染DOM以外,还可以实现SSR(Nuxt.js/Next.js)、原生应用(Weex/React Native)、小程序(mpvue/uni-app)等
Virtual DOM库
-
- Vue2.x内部使用的Virtual DOM就是改造的Snabbdom
- 大约200SLOC(single line of code)
- 通过模块可扩展
- 源码使用TypeScript开发
- 最快的Virtual DOM之一
-
Snabbdom的核心仅提供最基本的功能,只导出了三个函数,init()、h()、thunk()
- init()是一个高阶函数,返回patch() (对比两个VNode的差异更新到真实DOM)
- h()返回虚拟节点VNode,这个函数我们在使用Vue.js的时候见过
new Vue({ router, store, render: h => h(app) }).$mount('#app')
- thunk()是一种优化策略,可以在处理不可变数据时使用
创建Snabbdom项目
-
使用一个轻量的打包工具parcel
-
创建项目并安装parcel
# 创建项目目录
md snabbdom
# 进入到项目目录
cd snabbdom
# 创建package.json
npm init -y
# 本地安装parcel
npm i parcel-bundler -D
- 配置package.json中的scripts
"scrips": {
"dev": "parcel index.html --open",
"build: "parcel build index.html"
}
- 创建目录结构
1 ︳ index.html
2 ︳ package.json
3 ﹂src
4 ︳ basic.js
- 使用snabbdom
import {
init } from "snabbdom/build/package/init.js";
import {
h } from "snabbdom/build/package/h.js";
// init函数的参数是一个数组,数组内是模块
// 返回值是 patch函数, 作用是对比两个VNode的差异更新到真实DOM
let patch = init(