什么是高阶组件:
高阶组件就是一个函数,且该函数接受一个组件作为参数,并返回一个新的组件。
具体点高阶组件其实就是装饰者模式的应用: 在不改变对象自身的前提下在程序运行期间动态的给对象添加一些额外的属性或行为。
例子:
// 一个函数就是一个组件。所以组件是函数这个命题成立了。所谓高阶组件其实就是一个高阶函数, 即返回一个组件函数的函数
// 回忆高阶组件的定义:接收一个组件作为参数,返回一个新的组件
// Vue中组件就是个函数,但是在引入之前仍只是一个options对象,所以这样就很好明白了 Vue中组件开始只是一个对象,即高阶组件就是:一个函数接受一个纯对象,并且返回一个新纯对象
// 1.高阶组件(HOC)应该是无副作用的纯函数,且不应该修改原组件,即原组件不能有变动
// 2.高阶组件(HOC)不关心你传递的数据(props)是什么,并且新生成组件不关心数据来源
// 3.高阶组件(HOC)接收到的 props 应该透传给被包装组件即直接将原组件prop传给包装组件
// 4.高阶组件完全可以添加、删除、修改 props
export default function Console(BaseComponent) {
return {
props: BaseComponent.props,
mounted() {
console.log("高阶组件");
},
render(h) {
console.log(this);
// 将 this.$slots 格式化为数组,因为 h 函数第三个参数是子节点,是一个数组
const slots = Object.keys(this.$slots)
.reduce((arr, key) => arr.concat(this.$slots[key]), [])
.map((vnode) => {
vnode.context = this._self; // 绑定到高阶组件上,vm:解决具名插槽被作为默认插槽进行渲染
return vnode;
});
// 透传props、透传事件、透传slots
return h(
BaseComponent,
{
on: this.$listeners,
attrs: this.$attrs, // attrs 指的是那些没有被声明为 props 的属性
props: this.$props,
},
slots
);
},
};
}
import Base from "@/components/Base.vue";
import Console from "@/hoc/Console.js";
const wrapBase = Console(Base);
Vue.component("wrap-base", wrapBase);