----
![](https://ask.qcloudimg.com/http-save/yehe-8223537/f163c2a0bc33f3c30ef16e98171f06d5.png)
一、高阶组件概念
![](https://ask.qcloudimg.com/http-save/yehe-8223537/3cf65f3ed50c4bc3e8b1781885ebb6cc.png)
何谓高阶组件?类比高阶函数的定义:将函数作为参数的函数就是高阶函数,那么,将组件作为参数的组件就是高阶组件。
![](https://ask.qcloudimg.com/http-save/yehe-8223537/8cbd112977936a314030fd370c56a6de.png)
二、目标
假如我们有一个组件,我们希望通过某个函数,去扩展它,得到一个新的组件,新的组件有完全的参数组件的行为,如果这点可以满足,那么其他扩展就可以针对性的进行处理了。组件最重要的三个功能就是事件、属性以及插槽,通过函数得到新的组件如果能完全复制参数组件的这三项能力,那么这个函数就是一个合格的高阶组件。
三、思路
通过组件的render函数基于参数组件的模板进行属性、事件乃至插槽的捆绑
四、准备
我们先定义一个baseComp,一个函数hoc.js,将baseComp传入得到wrapperComp
baseComp.vue
props[p] =======> {
{p}}
data[myProp] =======> {
{myProp}}
--------------------插槽分割线--------------------
hoc.js
export default function Wrapper(baseComp) {
return {
data() {
return {};
},
mounted() {},
render(h) {
return h(baseComp, {})
}
}
}
app.vue
/********************** baseComp start **********************/
我是一个默认插槽:base默认slot
我是一个具名插槽:base具名slot
/********************** baseComp end **********************/
/********************** wrapperComp start **********************/
我是一个默认插槽:wrapper默认slot
我是一个具名插槽:wrapper具名slot
/********************** wrapperComp end **********************/
我们通过将baseComp传递给hoc.js得到wrapperComp组件,目前只是将模板进行复制,我们来看看效果:
如图我们已经完成一个组件生成另一个组件了,但是你会发现,属性、插槽以及事件都不能正确传递,接下来我们依次实现
五、实现
1、属性、事件
hoc.js
...
render(h) {
return h(baseComp, {
on: this.$listeners,
attrs: this.$attrs,
props: this.$props
})
}
...
点击下方按钮也能触发事件了
2、插槽
hoc.js
...
render(h) {
let scopedSlots = {};
let $slots = this.$slots;
Object.keys($slots).map((key) => (scopedSlots[key] = () => $slots[key]))
return h(baseComp, {
on: this.$listeners,
attrs: this.$attrs,
props: this.$props,
scopedSlots
})
}
...
插槽内容也能传递
六、难点
1、忽略 props 使得声明的属性没有传递
2、使用this.slots绑定插槽:插槽内容无法按照插槽顺序渲染(因为只是简单的模板列表的平铺,不涉及作用域属性)
Reference
1、Discussion: Best way to create a HOC
https://github.com/vuejs/vue/issues/6201
2、探索Vue高阶组件
http://hcysun.me/2018/01/05/%E6%8E%A2%E7%B4%A2Vue%E9%AB%98%E9%98%B6%E7%BB%84%E4%BB%B6/
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/hz/143049.html