4.2 Vnode

Vue在渲染机制的优化上,同样引进了virtual dom的概念,它是用Vnode这个构造函数去描述一个DOM节点。

4.2.1 Vnode构造函数

  1. var VNode = function VNode (tag,data,children,text,elm,context,componentOptions,asyncFactory) {
  2. this.tag = tag; // 标签
  3. this.data = data; // 数据
  4. this.children = children; // 子节点
  5. this.text = text;
  6. ···
  7. ···
  8. };

Vnode定义的属性差不多有20几个,显然用Vnode对象要比真实DOM对象描述的内容要简单得多,它只用来单纯描述节点的关键属性,例如标签名,数据,子节点等。并没有保留跟浏览器相关的DOM方法。除此之外,Vnode也会有其他的属性用来扩展Vue的灵活性。

源码中也定义了创建Vnode的相关方法。

4.2.2 创建Vnode注释节点

  1. // 创建注释vnode节点
  2. var createEmptyVNode = function (text) {
  3. if ( text === void 0 ) text = '';
  4. var node = new VNode();
  5. node.text = text;
  6. node.isComment = true; // 标记注释节点
  7. return node
  8. };

4.2.3 创建Vnode文本节点

  1. // 创建文本vnode节点
  2. function createTextVNode (val) {
  3. return new VNode(undefined, undefined, undefined, String(val))
  4. }

4.2.4 克隆vnode

  1. function cloneVNode (vnode) {
  2. var cloned = new VNode(
  3. vnode.tag,
  4. vnode.data,
  5. vnode.children && vnode.children.slice(),
  6. vnode.text,
  7. vnode.elm,
  8. vnode.context,
  9. vnode.componentOptions,
  10. vnode.asyncFactory
  11. );
  12. cloned.ns = vnode.ns;
  13. cloned.isStatic = vnode.isStatic;
  14. cloned.key = vnode.key;
  15. cloned.isComment = vnode.isComment;
  16. cloned.fnContext = vnode.fnContext;
  17. cloned.fnOptions = vnode.fnOptions;
  18. cloned.fnScopeId = vnode.fnScopeId;
  19. cloned.asyncMeta = vnode.asyncMeta;
  20. cloned.isCloned = true;
  21. return cloned
  22. }

注意:cloneVnodeVnode的克隆只是一层浅拷贝,它不会对子节点进行深度克隆。