Snabbdom 使用

154 阅读1分钟

开始使用

Sanbbdom 是一个虚似DOM库,将DOM操作抽象成几个简单的API,其优点是体积小只有200多KB,性能高,

基本使用

import {
  init, // 初始化DOM更新的对象
  toVNode, // 将DOM节点转换成虚似DOM节点
  classModule,//支持class模块 对象 class{ class: { active: true, selected: false } } 
  propsModule, // 支持属性传入模块 对象 { props { props: { href: "/foo" } } }
  styleModule, // 支持样式模块 对象 { style: { fontWeight: "bold" } }
  eventListenersModule,// 支持事件模块 对象 { on: { click: someFn } }
  h// 渲染方法
} from "snabbdom";

const patch = init([
  // 通过传入模块初始化 patch 函数
  classModule, // 开启 classes 功能
  propsModule, // 支持传入 props
  styleModule, // 支持内联样式同时支持动画
  eventListenersModule // 添加事件监听
]);

const container = document.getElementById("container");

const vnode = h("div#container.two.classes", { on: { click: someFn } }, [
  h("span", { style: { fontWeight: "bold" } }, "This is bold"),
  " and this is just normal text",
  h("a", { props: { href: "/foo" } }, "I'll take you places!")
]);
// 传入一个空的元素节点 - 将产生副作用(修改该节点)
patch(container, vnode);

const newVnode = h(
  "div#container.two.classes",
  { on: { click: anotherEventHandler } },
  [
    h(
      "span",
      {
          style: { fontWeight: "normal", fontStyle: "italic" }
          hook: {
            create: () => {
              console.log("create")
            }
          },
      },
      "This is now italic type"
    ),
    " and this is still just normal text",
    h("a", { props: { href: "/bar" }, class: { active: true, selected: false } }, "I'll take you places!")
  ]
);
// 再次调用 `patch`
patch(vnode, newVnode); // 将旧节点更新为新节点

优化DOM处理

此方法会在patch 检查number是否改变如果未改变会不做DOM更新

function numberView(n) {
  return h("div", "Number is: " + n);
}

function render(state) {
  return thunk("num", numberView, [state.number]);
}

虚似DOM节构

sel: "h1",// 标签描述,能描述标签以及ID与class 
data: {}, //  当前元素的属性对象
children: undefined, 子虚似列表
text: "Hello, World", // 文本内容
elm: Element,// 指向DOM元素
key: undefined // 惟一key

BUG处理

在webpack 使用如果报错

ERROR in ./node_modules/snabbdom/build/jsx.js 2:0-24 Module not found: Error: Can't resolve './h'

找到jsx.js 中的./h 换成 ./h.js就可以了