前言
首先最好了解一下Vue中的虚拟DOM
Snabbdom模拟虚拟DOM实现原理
Snabbdom 基本使用
Snabbdom 中的模块
模块的作用
- Snabbdom 的核心库并不能处理 DOM 元素的属性/样式/事件等,可以通过注册 Snabbdom 默认提供的模块来实现
- Snabbdom 中的模块可以用来扩展 Snabbdom的功能
- Snabbdom 中的模块的实现是通过注册全局的钩子函数来实现的
官方提供的模块
- attributes
设置VNode对应的DOM元素的属性
内部使用的是DOM的标准方法setAttributes来实现的,这个模块内部会对DOM对象布尔类型的属性做判断(如selected、checked等)
- props
props和attributes都是用来设置VNode对应的DOM元素的属性
不同的是props模块内部设置DOM对象的属性是通过 对象.属性 的方式来设置的,另外它内部不会去处理布尔类型的属性
- dataset
dataset用来处理HTML5中的
data-
这样的属性
- class
class不是用来设置类样式的,而是用来切换类样式的
如果想要设置类样式,可以通过h函数的第一个参数来设置
- style
style用来设置行内样式,并且使用这个模块很容易设置过度动画
- eventlisteners
eventlisteners用来注册和移除事件
模块使用步骤
- 导入需要的模块
- 这些模块是单独存在的,并没有在snabbdom核心库中,类似于插件
- init() 中注册模块
- init函数的参数是个数组,把要注册的模块方法这个数组中
- h() 函数的第二个参数处使用模块
- 第二个参数可以设置为对象,这个对象就是设置模块中所需要的数据。这里可以设置DOM的属性、行内样式、事件等
Demo
import { init } from 'snabbdom/build/package/init'
import { h } from 'snabbdom/build/package/h'
// 1. 导入模块
import { styleModule } from 'snabbdom/build/package/modules/style'
import { eventListenersModule } from 'snabbdom/build/package/modules/eventlisteners'
// 2. 注册模块
const patch = init([
styleModule,
eventListenersModule
])
// 3. 使用h() 函数的第二个参数传入模块中使用的数据(对象)
let vnode = h('div', [
h('h1', { style: { backgroundColor: 'red' } }, 'Hello World'),
h('p', { on: { click: eventHandler } }, 'Hello P')
])
function eventHandler() {
console.log('点击事件触发了')
}
let app = document.querySelector('#app')
patch(app, vnode)