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

这里的关键点除了你需要了解 Vue 处理 slot 的方式之外,你还要知道通过当前实例 _self 属性访问当实例本身,而不是直接使用 this ,因为 this 是一个代理对象。

现在貌似看上去没什么问题了,不过我们还忘记了一件事儿,即 scopedSlots ,不过 scopedSlotsslot 的实现机制不一样,本质上 scopedSlots 就是一个接收数据作为参数并渲染 VNode 的函数,所以不存在 context 的概念,所以直接透传即可:

hoc.js

function WithConsole (WrappedComponent) {
 return {
 mounted () {
  console.log('I have already mounted')
 },
 props: WrappedComponent.props,
 render (h) {
  const slots = Object.keys(this.$slots)
  .reduce((arr, key) => arr.concat(this.$slots[key]), [])
  .map(vnode => {
   vnode.context = this._self
   return vnode
  })

  return h(WrappedComponent, {
  on: this.$listeners,
  props: this.$props,
  // 透传 scopedSlots
  scopedSlots: this.$scopedSlots,
  attrs: this.$attrs
  }, slots)
 }
 }
}

到现在为止,一个高阶组件应该具备的基本功能算是实现了,但这仅仅是个开始,要实现一个完整健壮的 Vue 高阶组件,还要考虑很多内容,比如:

函数式组件中要使用 render 函数的第二个参数代替 this

以上我们只讨论了以纯对象形式存在的 Vue 组件,然而除了纯对象外还可以函数。

创建 render 函数的很多步骤都可以进行封装。

处理更多高阶函数组件本身的选项( 而不仅仅是上面例子中的一个简单的生命周期钩子 )

我觉得需要放上两个关于高阶组件的参考链接,供参考交流:

Discussion: Best way to create a HOC

https://github.com/jackmellis/vue-hoc

为什么在 Vue 中实现高阶组件比较难

前面说过要分析一下为什么在 Vue 中实现高阶组件比较复杂而 React 比较简单。这主要是二者的设计思想和设计目标不同,在 React 中写组件就是在写函数,函数拥有的功能组件都有。而 Vue 更像是高度封装的函数,在更高的层面 Vue 能够让你轻松的完成一些事情,但与高度的封装相对的就是损失一定的灵活,你需要按照一定规则才能使系统更好的运行。

有句话说的好:

会了不难,难了不会

复杂还是简单都是相对而言的,最后希望大家玩的转 Vue 也欣赏的了 React 。放上两张我比较认同的图片供各位看官讨论:

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

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