Skip to content

前言

组件实例中令人疑惑的两个属性,名字相同表现却不同

组件Vnode和元素vnode的区别

元素的vnode比较简单,会children这个属性,组件没有

js
// element vnode
interface ElementVnode {
    tag: string;
    data: {
        on: {},
        attrs: { 
            [p: string]:
        },
    },
    parent: Vnode,  // 在写render函数时没有这个parent,在_render()中添加Vnode的parent为当前Vnode
    Children: Vnode[]
}

// component vnode
render(h) {
    return <HelloWorld msg={123} vOn:click={() => {}}> 123 </HelloWorld>
}

const componentVnode = {
    tag: 'vue-component-2-HelloWorld',
    data: {

    },
    componentOptions: {
        Ctor: function() {}   // 组件的构造函数
        children: [Vnode]   // 123那个文本节点
        listeners: {  // 运行时数据
            click: () => {}
        }
        propsData: {  // 运行时传入的一些数据
            msg: 123
        }
    },
    componentInstance: undefined,
    children: undefined
}

// 构造函数上是组件申明时的一些数据
Ctor.options

_vnode 来源

指的就是当前实例render后产生的vnode

js
Vue.prototype._update = function (vnode, hydrating) {
    var vm = this;
    var prevEl = vm.$el;
    var prevVnode = vm._vnode;
    var restoreActiveInstance = setActiveInstance(vm);
    vm._vnode = vnode;
    // ....
}

$vnode

指的是该组件对应的vnode,在父组件中该组件的vnode,也就是tag: 'vue-component-2-helloWorld' 这个vnode