本文为拉勾网大前端高薪训练营第一期笔记
虚拟DOM就是js对象描述dom对象,成本比真实DOM低很多,因为真实DOM的属性特别多
以snabbdom为例,导入时需要这样写
import {init, h, thunk} from 'snabbdom'
md snabbdom-demo
cd snabbdom-demo
yarn init -y
yarn add parcel-bundler
//package.json
scripts:
dev: parcel index.html --open
build: parcel build index.html
import { h, init } from 'snabbdom'
// 1. hello world
// 参数:数组,模块
// 返回值:patch函数,作用对比两个vnode的差异更新到真实DOM
let patch = init([])
// 第一个参数:标签+选择器
// 第二个参数:如果是字符串的话就是标签中的内容
let vnode = h('div#container.cls', {
hook: {
init (vnode) {
console.log(vnode.elm)
},
create (emptyVnode, vnode) {
console.log(vnode.elm)
}
}
}, 'Hello World')
let app = document.querySelector('#app')
// 第一个参数:可以是DOM元素,内部会把DOM元素转换成VNode
// 第二个参数:VNode
// 返回值:VNde
let oldVnode = patch(app, vnode)
//此时页面上是Hello World
vnode = h('div', 'Hello Snabbdom')
patch(oldVnode, vnode)
//此时页面上是Hello Snabbdom,对比了oldVnode和vnode的差异,然后更新
// 2. div中放置子元素 h1,p
import { h, init } from 'snabbdom'
let 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', 'Hello P')
])
patch(oldVnode, vnode)
// 清空页面元素 -- 错误
// patch(oldVnode, null)
// 传注释节点来清空页面元素
patch(oldVnode, h('!'))
}, 2000);
官方提供了6个模块
以style和eventlisteners为例
import { init, h } 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', {
style: {
backgroundColor: 'red'
},
on: {
click: eventHandler
}
}, [
h('h1', 'Hello Snabbdom'),
h('p', '这是p标签')
])
function eventHandler () {
console.log('点击我了')
}
let app = document.querySelector('#app')
let oldVnode = patch(app, vnode)
vnode = h('div', 'hello')
patch(oldVnode, vnode)
对比节点时是对比sel key,如果没有key,就认为两个li是一样的,此时直接更新text