美文网首页
Vue Virtual DOM 源码解析

Vue Virtual DOM 源码解析

作者: 阿畅_ | 来源:发表于2018-08-28 23:38 被阅读12次
  • Virtual DOM 这个概念相信大多数的开发人员都不会陌生,它产生的前提就是操作浏览器中的 DOM 是很 ·昂贵· 的,为了更直观的看到,我把一个简单的 div 元素的属性打印出来:


    demo.png
  • 上面可以看到,真正的 DOM 元素是非常庞大的,当我们频繁的去做 DOM 操作,会产生一定的性能问题。

  • 而 Virtual DOM 就是一个用原生的 JS 对象去描述一个 DOM 节点,所以它比创建一个 DOM 的代价要小很多。在 Vue.js 中,Virtual DOM 就是用 VNode 这个一个 class 去描述,定义在 src/core/vdom/vnode.js 中:

export default class VNode {
  tag: string | void;
  data: VNodeData | void;
  children: ?Array<VNode>;
  text: string | void;
  elm: Node | void;
  ns: string | void;
  context: Component | void; // rendered in this component's scope
  key: string | number | void;
  componentOptions: VNodeComponentOptions | void;
  componentInstance: Component | void; // component instance
  parent: VNode | void; // component placeholder node

  // strictly internal
  raw: boolean; // contains raw HTML? (server only)
  isStatic: boolean; // hoisted static node
  isRootInsert: boolean; // necessary for enter transition check
  isComment: boolean; // empty comment placeholder?
  isCloned: boolean; // is a cloned node?
  isOnce: boolean; // is a v-once node?
  asyncFactory: Function | void; // async component factory function
  asyncMeta: Object | void;
  isAsyncPlaceholder: boolean;
  ssrContext: Object | void;
  fnContext: Component | void; // real context vm for functional nodes
  fnOptions: ?ComponentOptions; // for SSR caching
  fnScopeId: ?string; // functional scope id support

  constructor (
    tag?: string,
    data?: VNodeData,
    children?: ?Array<VNode>,
    text?: string,
    elm?: Node,
    context?: Component,
    componentOptions?: VNodeComponentOptions,
    asyncFactory?: Function
  ) {
    this.tag = tag
    this.data = data
    this.children = children
    this.text = text
    this.elm = elm
    this.ns = undefined
    this.context = context
    this.fnContext = undefined
    this.fnOptions = undefined
    this.fnScopeId = undefined
    this.key = data && data.key
    this.componentOptions = componentOptions
    this.componentInstance = undefined
    this.parent = undefined
    this.raw = false
    this.isStatic = false
    this.isRootInsert = true
    this.isComment = false
    this.isCloned = false
    this.isOnce = false
    this.asyncFactory = asyncFactory
    this.asyncMeta = undefined
    this.isAsyncPlaceholder = false
  }

  // DEPRECATED: alias for componentInstance for backwards compat.
  /* istanbul ignore next */
  get child (): Component | void {
    return this.componentInstance
  }
}
  • 上面可以看到 Vue.js 中的 Virtual DOM 的定义还是略微复杂一些,因为它这里包含了很多 Vue 的特性。实际上 Vue 中 Virtual DOM 是借鉴了一个开源库 snabbdom 的实现,然后加入了一些 Vue 特色的东西。还是建议去看一下这个开源库,而我后面页面写一篇关于这个开源库的文章。

其实 VNode 是对真实 DOM 的一种抽象描述,它的核心定义无非就是几个关键属性,例如: 标签名、数据、子节点、键值等。其它属性都是用来扩展 VNode 的灵活性以及实现一些特殊的 feature 的。由于 VNode 知识用来映射到真实 DOM 的渲染,不需要包含操作 DOM 的方法,因此它是非常轻量和简单的。

Virtual DOM 除了它的数据结构的定义,映射到真实的 DOM 实际上要经历 VNode 的 create、diff、patch 等过程。

相关文章

网友评论

      本文标题:Vue Virtual DOM 源码解析

      本文链接:https://www.haomeiwen.com/subject/xrvcwftx.html