探索Vue高阶组件的使用(7)

DOM 之外,还有组件,如下:

var render = function() {
 var _vm = this
 var _h = _vm.$createElement
 var _c = _vm._self._c || _h
 return _c("div", [
  _c("h2", {
   attrs: { slot: "slot1" },
   slot: "slot1"
  }, [
   _vm._v("BaseComponent slot")
  ])
 ])
}

那么生成的渲染函数( render )是这样的:

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

我们发现无论是普通DOM还是组件,都是通过 _c 函数创建其对应的 VNode 的。其实 _cVue 内部就是 createElement 函数。 createElement 函数会自动检测第一个参数是不是普通DOM标签,如果不是普通DOM标签那么 createElement 会将其视为组件,并且创建组件实例, 注意组件实例是这个时候才创建的 。但是创建组件实例的过程中就面临一个问题: 组件需要知道父级模板中是否传递了 slot 以及传递了多少,传递的是具名的还是不具名的等等 。那么子组件如何才能得知这些信息呢?很简单,假如组件的模板如下:

var render = function() {
 var _vm = this
 var _h = _vm.$createElement
 var _c = _vm._self._c || _h
 return _c(
  "div",
  [
   _c("base-component", [
    _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 之后进入到了关键的一步,这一步就是导致高阶组件中透传

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/467.html