Snabbdom基本使用
一.创建项目
打包工具为了方便使用 parcel
# 创建项目目录
md snabbdom-demo
# 进入项目目录
cd snabbdom-demo
# 创建 package.json yarn init -y
# 本地安装 parcel
yarn add parcel-bundler
配置 package.json 的 scripts
"scripts": {
"dev": "parcel index.html --open",
"build": "parcel build index.html"
}
创建目录结构
│ index.html
│ package.json
└─src
01-basicusage.js
Index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>snabbdom-demo</title>
</head>
<body>
<div id="app"></div>
<script src="./src/01-basicusage.js"></script>
</body>
</html>
二.导入 Snabbdom
2.1 安装Snabbdom 0.7版本
yarn add snabbdom @0.7
2.2 导入Snabbdom
在01-basicusage.js
中导入snabbdom.
Snabbdom 的官网 demo 中导入使用的是commonjs
模块化语法,我们使用更流行的 ES6 模块化的语法import
关于模块化的语法请参考阮一峰老师的 Module 的语法 .
import {h,thunk,init} from 'snabbdom';
注意
:导入时候不能使用 import snabbdom from ‘snabbdom’,原因是:node_modules/src/snabbdom.ts 末尾导出使用的语法是export
导出 API,没有使用 export default
导出默认输出
2.3 Snabbdom 核心功能
init()
$参数:数组,模块
$返回值:patch函数,作用对比两个vnode的差异功更新到真实DOM
h()
$参数:(标签+选择器,如果是字符串就是内容)
$返回值:返回虚拟节点VNode
,这个函数我们在使用 Vue.js 的时候见过
thunk()
$参数:(可以是DOM元素,VNode)
$返回值:VNode
三.案例演示
3.1 实现hello world
import {h,thunk,init} from 'snabbdom';
// 1.hello world
let patch = init([])
// 使用h函数创建虚拟DOM
let vnode = h('div#container.cls','Hello World')
let app = document.querySelector('#app')
// 使用patch函数将真实DOM转换成虚拟DOM然后对比他们的差异,更新到真实DOM并返回一个虚拟DOM
let oldVnode = patch(app,vnode)
vnode = h('div','Hello Snabbdom')
patch(oldVnode,vnode)
3.2 实现div中放置子元素h1 ,p
import { init, h, thunk } from 'snabbdom'
// 使用 init() 函数创建 patch()
// init() 的参数是数组,将来可以传入模块,处理属性/样式/事件等 let patch = init([])
// 使用 h() 函数创建 vnode let vnode = h('div.cls', [
h('h1', 'Hello Snabbdom'),
h('p', '这是段落') ])
const app = document.querySelector('#app') // 把 vnode 渲染到空的 DOM 元素(替换)
// 会返回新的 vnode
let oldVnode = patch(app, vnode)
setTimeout(() => {
vnode = h('div.cls', [
h('h1', 'Hello World'),
h('p', '这是段落') ])
// 把老的视图更新到新的状态
oldVnode = patch(oldVnode, vnode)
// 卸载 DOM,文档中 patch(oldVnode, null) 有误 // h('!') 是创建注释
patch(oldVnode, h('!'))
}, 2000)
4.模块
Snabbdom 的核心库并不能处理元素的属性/样式/事件
等,如果需要处理的话,可以使用模块.
4.1 官方提供的 6 个模块
attributes
设置 DOM 元素的属性,使用 setAttribute ()
处理布尔类型的属性
props
和 attributes 模块相似,设置 DOM 元素的属性 element[attr] = value
不处理布尔类型的属性
class
切换类样式
注意:给元素设置类样式是通过 sel 选择器
dataset
设置 data-* 的自定义属性
eventlisteners
注册和移除事件
style
设置行内样式,支持动画delayed/remove/destroy
4.2 模块使用步骤
1.
导入
需要的模块2.在
init()
中注册模块3.使用
h()
函数创建 VNode 的时候,可以把第二个参数设置为对象
,其他参数往后移
4.3 代码演示
//模块使用
import {h,thunk,init} from 'snabbdom';
//1.导入模块
import style from 'snabbdom/modules/style'
import eventlisteners from 'snabbdom/modules/eventlisteners'
//2.注册模块
let patch = init([
style,
eventlisteners
]);
//3.使用h()函数的第二个参数传入模块需要的数据(对象)
let vnode = h('div#container',{
style:{
backgroundColor:'red'
},
on:{
click:eventHandler
}
},[
h('h1','hello snabbdom'),
h('p','p标签'),
]);
function eventHandler (params) {
console.log('点击我了');
}
let app = document.querySelector('#app');
//渲染到真实的DOM
let oldVnode = patch(app,vnode);