snabbdom源码总结


snabbdom

使用流程

1、init: 使用模块初始化一个patch function;

const patch = init([styleModule, eventListenersModule]);

2、创建一个vnode;

let vnode = h('div#container.demo', [
  h('h1', { style: { backgroundColor: 'cyan' } }, 'title'),
  h('p', { on: { click: eventHandler } }, 'pppppp'),
  h('!', 'sdsdsd')
])

3、选择一个容器,将vnode patch到容器中;

const container = document.getElementById("container");
patch(container, vnode);

4、生成一个新的vnode;

const newVnode = h(
  "div#container.two.classes",
  { on: { click: anotherEventHandler } },
  [
    h(
      "span",
      { style: { fontWeight: "normal", fontStyle: "italic" } },
      "This is now italic type"
    ),
    " and this is still just normal text",
    h("a", { props: { href: "/bar" } }, "I'll take you places!"),
  ]
);

5、将旧vnode更新为新vnode;

patch(vnode, newVnode);

init模块

包含的关键函数:

  • createElm:根据传入的vnode递归创建一颗真实DOM树;
  • updateChildren:递归比较新传入的新旧节点以及子节点的差异(diff算法);
  • patchVnode:比较新老节点的差异(比较是否有子节点以及文本内容,新旧节点都有子节点时调用updateChildren);
  • patch:init模块导出的函数

patch函数

function patch(
  oldVnode: VNode | Element | DocumentFragment,
  vnode: VNode
): VNode

patch函数


patchVnode

function patchVnode(
  oldVnode: VNode,
  vnode: VNode,
  insertedVnodeQueue: VNodeQueue
)

patchVnode函数


updateChildren

function updateChildren(
  parentElm: Node,
  oldCh: VNode[],
  newCh: VNode[],
  insertedVnodeQueue: VNodeQueue
)
updateChildren

Diff算法的核心

四种更新策略,按比较的先后顺序排列,依次为:

(1)旧前与新前;

(2)旧后与新后;

(3)旧前与新后;

(4)旧后与新前;

(1)旧前与新前;

(2)旧后与新后

(3)旧前与新后

(4)旧后与新前


文章作者: elegantlee
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 elegantlee !
评论
  目录