VNode简介

68 阅读1分钟

虚拟dom是啥,格式,优缺点

_render 方法返回的就是一个 VNode 对象

blog.csdn.net/violetjack0…

export default class VNode {
  constructor (
    tag?: string,
    data?: VNodeData,
    children?: ?Array<VNode>,
    text?: string,
    elm?: Node,
    context?: Component,
    componentOptions?: VNodeComponentOptions,
    asyncFactory?: Function
  ) {
    this.tag = tag // 标签名
    this.data = data // 数据(vnodedata类型)
    this.children = children // 子节点
    this.text = text // 文本
    this.elm = elm // 当前节点对应的真实dom节点
    this.ns = undefined // 命名空间
    this.context = context // 当前节点上下文
    this.fnContext = undefined // 函数组件上下文
    this.fnOptions = undefined // 函数组件配置项
    this.fnScopeId = undefined // 函数组件ScopeId
    this.key = data && data.key // 子节点key属性
    this.componentOptions = componentOptions // 组件项配置
    this.componentInstance = undefined // 组件实例
    this.parent = undefined // 当前节点的父节点
    this.raw = false // 是否为原生html或者知识普通文本
    this.isStatic = false // 静态节点标志keep-alive
    this.isRootInsert = true // 是否为跟节点插入
    this.isComment = false // 是否为注释节点
    this.isCloned = false  // 是否为克隆节点
    this.isOnce = false // 是否为v-once节点
    this.asyncFactory = asyncFactory // 异步工厂方法
    this.asyncMeta = undefined // 异步mate
    this.isAsyncPlaceholder = false // 是否为异步占位
  }

  // DEPRECATED: alias for componentInstance for backwards compat.
  /* istanbul ignore next */
  get child (): Component | void {
    return this.componentInstance
  }
}

模板

    <div id="app">
        <span>{{ message }}</span>
        <ul>
            <li v-for="item of list" class="item-cls">{{ item }}</li>
        </ul>
    </div>

    <script>
        new Vue({
            el'#app',
            data: {
                message'hello Vue.js',
                list: ['jack''rose''james']
            }
        })
    </script>

此模板对应的vnode

{
    "tag": "div",
    "data": {
        "attr": { "id": "app" }
    },
    "children": [
        {
            "tag": "span",
            "children": [
                { "text": "hello Vue.js" }
            ]
        },
        {
            "tag": "ul",
            "children": [
                {
                    "tag": "li",
                    "data": { "staticClass": "item-cls" },
                    "children": [
                        { "text": "jack" }
                    ]
                },
                {
                    "tag": "li",
                    "data": { "staticClass": "item-cls" },
                    "children": [
                        { "text": "rose" }
                    ]
                },
                {
                    "tag": "li",
                    "data": { "staticClass": "item-cls" },
                    "children": [
                        { "text": "james" }
                    ]
                }
            ]
        }
    ],
    "context": "$Vue$3",
    "elm": "div#app"
}

在看VNode的时候小结以下几点:

* 所有对象的 context 选项都指向了 Vue 实例。

* elm 属性则指向了其相对应的真实 DOM 节点。

* DOM 中的文本内容被当做了一个只有 text 没有 tag 的节点。

* 像 class、id 等HTML属性都放在了 data 中