Snabbdom 的使用

Virtual Dom 库

Virtual Dom 就是又普通的 js 对象来描述 Dom 对象,因为 Dom 对象是非常庞大,而且兼容性不好,虚拟 Dom 在复杂视图中可以提升性能还可以跨平台使用。

Snabbdomvirtual-dom 就是两个出名的虚拟 Dom 的开源库。而 vue 内部就是引入了 Snabbdom,且它只有 200 行代码,易于学习,所以接下来要分析 Snabbdom 开源库。

创建项目

首先我们创建一个名为 snabbdom-demo 的项目目录,然后使用 npm 初始化项目,安装 parcel 打包工具:

js 复制代码
npm init -y
npm install parcel-bundler -D

修改项目的 package.json,配置 scripts:

js 复制代码
"scripts": {
    "dev": "parcel index.html --open",
    "build": "parcel build index.html"
  },

最后在项目目录下添加 index.htmlsrc/test1.js 文件,并在 index.html 中引入 src/test1.js

js 复制代码
<body>
  <div id="app"></div>
  <script src="./src/test1.js"></script>
</body>

使用示例

学习 snabbdom 的第一步就是查看 snabbdom 文档,文档中介绍了很多方法的使用,我们重点看一下 inith 方法的使用。

js 复制代码
import { init } from 'snabbdom/build/package/init'
import { h } from 'snabbdom/build/package/h'

const patch = init([])

let vnode = h('div#container.cls', 'Hello World')
// #app 占位
let app = document.querySelector('#app')
let oldVnode = patch(app, vnode)

setTimeout(() => {
    // 清除div中的内容,替换为空的注释节点
    patch(oldVnode, h('!'))
}, 2000);

这里使用从'snabbdom/build/package/init',而不是像文档中的使用'snabbdom/init'是因为 parcel 不支持 package.json 中的 exports,如果是 webpack5 是支持的。

运行界面

js 复制代码
npm run dev

我们可以看到界面显示 Hello World,元素为 <div id="container" class="cls">Hello World</div> ,然后两秒后页面清空,元素为 <!---->

代码分析

从代码和运行结果看,我们可以理解 inith 函数的作用。

  1. init : 接收包含模块的数组,并返回一个具有指定功能的 patch 函数
  2. h:接收两个参数,第一个参数表示标签+选择器,第二个参数如果是字符串就是标签中的文本内容,如果是数组就是子元素。
js 复制代码
let vnode = h('div#container', [
  h('h1', 'Hello Snabbdom'),
  h('p', '这是一个p')
])
  1. patch : 对比两个 vnode,把两个 vnode 的差异更新到真实 Dom 上。第一个参数为旧的 VNode,可以 vnode 也可以是真实 DOM 元素,如果是真实 DOM 元素,在内部会转换为 vnode。第二个参数为新的 VNode。返回新的 VNode,可以作为下一次 patch 的旧的 VNode

模块

Snabbdom 的核心库并不能处理 DOM 元素的属性、样式、事件等,可以通过注册 Snabbdom 提供的模块来实现。

Snabbdom 官方提供了6个模块attributespropsdatasetclassstyleeventlisteners

使用

js 复制代码
// 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')
])
相关推荐
点燃银河尽头的篝火(●'◡'●)19 分钟前
【BurpSuite】Cross-site scripting (XSS 学徒部分:1-9)
前端·web安全·网络安全·xss
Jiaberrr1 小时前
手把手教你:微信小程序实现语音留言功能
前端·微信小程序·小程序·语音·录音
熊猫在哪1 小时前
安装nuxt3
前端·nuxt.js
安冬的码畜日常1 小时前
【CSS in Depth 2 精译_036】5.6 Grid 网格布局中与对齐相关的属性 + 5.7本章小结
前端·css·css3·html5·网格布局·grid·css网格
啧不应该啊2 小时前
vue配置axios
前端·javascript·vue.js
__fuys__3 小时前
【HTML样式】加载动画专题 每周更新
前端·javascript·html
Want5953 小时前
HTML粉色烟花秀
前端·css·html
让开,我要吃人了3 小时前
HarmonyOS鸿蒙开发实战(5.0)自定义全局弹窗实践
前端·华为·移动开发·harmonyos·鸿蒙·鸿蒙系统·鸿蒙开发
yanlele3 小时前
前端面试第 66 期 - Vue 专题第二篇 - 2024.09.22 更新前端面试问题总结(20道题)
前端·javascript·面试
一条晒干的咸魚3 小时前
响应式CSS 媒体查询——WEB开发系列39
前端·css·html·css3·响应式设计·媒体查询