md snabbdom-demo
cd snabbdom-demo
npm init -y
npm install parcel-bundler -D
注意:以上操作在 管理员身份运行的cmd窗口中操作,否则可能会在最后一步报错
"scripts": {
"dev": "parcel index.html --open",
"build": "parcel build index.html"
},
创建完项目之后,要导入 Snabbdom
npm install snabbdom@2.1.0
通过使用Snabbdom 模拟演示虚拟DOM的实现原理
index.html 引入 01-basicusage.js
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>Snabbdom-demotitle>
head>
<body>
<div id="app">div>
<script src="./src/01-basicusage.js">script>
body>
html>
01-basicusage.js
import { init } from 'snabbdom/build/package/init'
import { h } from 'snabbdom/build/package/h'
const patch = init([])
/**
* init函数(patch函数)作用:把虚拟 DOM 转化为真实 DOM 并挂载到 DOM树上
* h函数作用:创建虚拟 DOM,这里创建的是 vnode 虚拟节点
* vnode作用:描述真实 DOM
*/
/**
* h函数参数
* 第一参数:标签+选择器
*
* 第二个参数:
* 如果是字符串就是标签中的文本内容
* 如果想要嵌套子元素,则第二个参数是一个数组,数组中每个成员都是一个h函数
*
*/
// 创建一个vnode h('标签名#id.class')
let vnode = h('div#container.cls','Hello World')
// 获取页面上的id为app的div
let app = document.querySelector('#app')
// 调用patch 比较两个vnode,把两个vnode的差异更新到真实DOM上
/**
* patch函数参数
* 第一个参数:旧的 VNode,也可以是 DOM 元素
* 第二个参数:新的 VNode
*
* 返回值:返回一个新的 VNode,也就是第二个参数
* 返回的新 VNode 会作为下一次再调用patch时 旧的 VNode 即 把当前的状态保存起来
*/
let oldVnode = patch(app, vnode)
vnode = h('div#container.xxx','Hello Snabbdom')
patch(oldVnode, vnode)
运行
npm run dev
浏览器执行结果
index.html 引入 02-basicusage.js
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>Snabbdom-demotitle>
head>
<body>
<div id="app">div>
<script src="./src/02-basicusage.js">script>
body>
html>
02-basicusage.js
import { init } from 'snabbdom/build/package/init'
import { h } from 'snabbdom/build/package/h'
const patch = init([])
let vnode = h('div#container', [
h('h1', 'Hello Snabbdom'),
h('p', '这是一个p')
])
let app = document.querySelector('#app')
let oldVnode = patch(app, vnode)
// 模拟请求服务更新页面数据
setTimeout(() => {
vnode = h('div#container', [
h('h1', 'Hello World'),
h('p', '这是一个ppppppppppp')
])
patch(oldVnode, vnode)
// 清除div中的内容 '!'表示创建空的注释节点
// patch(oldVnode, h('!'))
}, 2000)
相关资源:Snabbdom 基本使用、了解Vue 虚拟DOM实现使用的Snabbdom