Vue2中如何创建高阶组件并预设部分Props?
Vue2 高阶组件预设并转发Props的实现方案
问题说明
我有一个包含多个Props的组件ComponentA.vue,代码如下:
// ComponentA.vue export default { props: { prop1: { type: Boolean, default: false }, prop2: Boolean, // ... 其他props prop7: Object } }
我希望创建一个高阶组件,预设部分Props(比如把prop1固定为true),同时将剩余所有传入的Props转发给ComponentA,本质上等价于手动编写如下组件:
<!-- HigherComponentA.vue --> <template> <ComponentA :prop1="true" :prop2="prop2" <!-- ... 其他props --> :prop7="prop7" ></ComponentA> </template> <script> export default { props: { prop2: Boolean, // ... 其他props prop7: Object } } </script>
我尝试过用render函数实现,但不知道怎么转发所有Props:
Vue.component("HigherComponentA", { render: (createElement) => { createElement(ComponentA, { props: { prop1: true } }) }, props: ComponentA.props });
请问在Vue2中有没有更简洁的实现方式?我经常需要现有组件的变体,每个变体都新建文件既不实用还会导致耦合。
解决方案
方法1:在render函数中合并预设Props与传入Props
利用Vue组件实例的$props属性获取所有传入的Props,再和预设的Props做合并(预设Props优先级更高,会覆盖传入的同名值):
import ComponentA from './ComponentA.vue' Vue.component("HigherComponentA", { props: ComponentA.props, // 继承原组件所有Props定义 render(createElement) { // 合并预设props和传入的props,预设props会覆盖传入的同名值 const mergedProps = { ...this.$props, prop1: true // 预设固定值 } return createElement(ComponentA, { props: mergedProps }) } })
方法2:用模板+v-bind="$props"实现
如果更习惯用模板写法,可以直接在模板中通过v-bind="$props"转发所有Props,再单独声明预设的Props(注意预设的Props可从当前组件的Props中移除,避免接收冗余参数):
<!-- HigherComponentA.vue --> <template> <ComponentA :prop1="true" v-bind="$props" ></ComponentA> </template> <script> import ComponentA from './ComponentA.vue' export default { // 复制原组件Props,移除要预设的prop1,避免接收冗余参数 props: Object.fromEntries( Object.entries(ComponentA.props).filter(([key]) => key !== 'prop1') ), // 如果不需要严格控制Props,也可以直接继承所有Props,此时传入的prop1会被预设值覆盖 // props: ComponentA.props } </script>
方法3:创建可复用的高阶组件工厂函数
如果需要给多个组件创建变体,可以封装一个通用的工厂函数,减少重复代码:
// createPresetComponent.js export function createPresetComponent(OriginalComponent, presetProps) { return { props: OriginalComponent.props, render(createElement) { const mergedProps = { ...this.$props, ...presetProps } return createElement(OriginalComponent, { props: mergedProps }) } } } // 使用示例 import ComponentA from './ComponentA.vue' import { createPresetComponent } from './createPresetComponent.js' const HigherComponentA = createPresetComponent(ComponentA, { prop1: true }) Vue.component("HigherComponentA", HigherComponentA)
内容的提问来源于stack exchange,提问作者Biopsy Alternator
相关产品推荐
相关产品推荐

