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')
])
相关推荐
崔庆才丨静觅8 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60619 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了9 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅9 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅10 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅10 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment10 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅10 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊11 小时前
jwt介绍
前端
爱敲代码的小鱼11 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax