探索Vue高阶组件的使用

2020-06-16 06:24:45易采站长站整理

_c("h2", { attrs: { slot: "slot1" }, slot: "slot1" }, [
_vm._v("BaseComponent slot")
]),
_vm._v(" "),
_c("p", [_vm._v("default slot")])
])
],
1
)
}

父组件的模板最终会生成父组件对应的

VNode
,所以以上模板对应的
VNode
全部由父组件所有,那么在创建子组件实例的时候能否通过获取父组件的
VNode
进而拿到
slot
的内容呢?即通过父组件将下面这段模板对应的
VNode
拿到:


<div>
<base-component>
<h2 slot="slot1">BaseComponent slot</h2>
<p>default slot</p>
</base-component>
</div>

如果能够通过父级拿到这段模板对应的

VNode
,那么子组件就知道要渲染哪些
slot
了,其实
Vue
内部就是这么干的,实际上你可以通过访问子组件的
this.$vnode
来获取这段模板对应的
VNode

其中

this.$vnode
并没有写进
Vue
的官方文档。子组件拿到了需要渲染的
slot
之后进入到了关键的一步,这一步就是导致高阶组件中透传
slot
BaseComponent
却无法正确渲染的原因,看下图:

这张图与上一张图相同,在子组件中打印

this.$vnode
,标注中的
context
引用着
VNode
被创建时所在的组件实例,由于
this.$vnode
中引用的
VNode
对象是在父组件中被创建的,所以
this.$vnode
中的
context
引用着父实例。理论上图中标注的两个
context
应该是相等的:


console.log(this.$vnode.context === this.$vnode.componentOptions.children[0].context) // true