javascript virtual DOM

来源:互联网 发布:大数据资格认证 编辑:程序博客网 时间:2024/06/07 05:24

关于virtual Dom

一、createElement(): 用 JavaScript对象(虚拟树) 描述 真实DOM对象(真实树)
二、diff(oldNode, newNode) : 对比新旧两个虚拟树的区别,收集差异
三、patch() : 将差异应用到真实DOM树

或者

  1. Javascript DOM模型树(VTree),类似文档节点树(DOM)
    2.DOM模型树转节点树方法(VTree -> DOM)
    3.两个DOM模型树的差异算法(diff(VTree, VTree) -> PatchObject)
    4.根据差异操作节点方法(patch(DOMNode, PatchObject) -> DOMNode)

关于vTree 与 React的createElement

vtree

{    // tag的名字    tagName: 'p',    // 节点包含属性    properties: {        style: {            color: '#fff'        }    },    // 子节点    children: [],    // 节点变动识别    key: 1}

React createElement

react.createElement('div', null, [    // 子节点img    react.createElement('img', { src: "avatar.png", class: "profile" }),    // 子节点h3    react.createElement('h3', null, [[user.firstName, user.lastName].join(' ')])]);

一个简单的react.createElement实现 Create函数

function create(vds, parent) {  // 首先看看是不是数组,如果不是数组统一成数组  !Array.isArray(vds) && (vds = [vds]);  //  如果没有父元素则创建个fragment来当父元素  parent = parent || document.createDocumentFragment();  var node;  // 遍历所有VNode  vds.forEach(function (vd) {    // 如果VNode是文字节点    if (isText(vd)) {      // 创建文字节点      node = document.createTextNode(vd.text);    // 否则是元素    } else {      // 创建元素      node = document.createElement(vd.tag);    }    // 将元素塞入父容器    parent.appendChild(node);    // 看看有没有子VNode,有孩子则处理孩子VNode    vd.children && vd.children.length &&      create(vd.children, node);    // 看看有没有属性,有则处理属性    vd.properties &&      setProps({ style: {} }, vd.properties, node);  });  return parent;}

DIFF算法

示意图

这里写图片描述


词汇概念

a. VNode

VNode 虚拟节点,它可以代表一个真实的 dom 节点。通过 createElement 方法能将 VNode 渲染成 dom 节点。

b. VText

VText 虚拟文本节点,代表了一个真实的文本节点。内容中若有 HTML 会被转义。

c. Hooks

Hooks 钩子方法,如给节点注册 ev-click 等事件。

d. Thunk

Thunk 方法允许开发者参与 diff 过程。如对于某节点,能够预先判断状态不会发生改变,则可以通过此方法,在 diff 过程中直接返回旧 VNode 。

e. Widget

Widget 和 Thunk 的作用有点相似,但它参与的是 patch 的过程。它能定制如何渲染成最终的 dom 节点。如要求某个状态只为偶数时,重新渲染等。

f. VPatch

VPatch 权且称之为「补丁对象 」,它描述了对于某个节点的具体操作,比如删除,插入,排序等等。