使用插槽而非内联声明是否可提升Vue通用网格组件的灵活性?
解决方案
完全可以通过作用域插槽实现你要的通用网格外壳效果,这也是这种无业务绑定的容器类组件的最佳实践,可完全移除所有内部硬编码的子组件引用和类型判断逻辑。
改造后的通用网格组件(MyUniversalComponent.vue)
不需要引入任何业务子组件,只保留网格基础布局和参数接收逻辑:
export default { props: { items: { type: Array, required: true } } }
模板部分把遍历到的条目数据透出给插槽,完全不干涉渲染逻辑:
<template> <div class="grid"> <div v-for="(item, index) in items" :key="index"> <slot :item="item" :index="index"></slot> </div> </div> </template>
父组件(Parent.vue)使用方式
业务子组件的引入、渲染判断完全由父层控制,和网格组件彻底解耦:
import DVD from '@/components/DVD.vue'; import Cassette from '@/components/Cassette.vue'; export default { components: { DVD, Cassette }, data() { return { items: [/* 你的业务数据列表 */] } } }
模板通过插槽接收网格组件透出的数据,自行实现渲染逻辑:
<template> <MyUniversalComponent :items="items"> <template #default="{ item }"> <DVD v-if="item.type === 'dvd'" :data="item" /> <Cassette v-else-if="item.type === 'cassette'" :data="item" /> <!-- 后续新增其他类型组件直接在这里扩展即可,不需要修改网格组件代码 --> </template> </MyUniversalComponent> </template>
可选优化方案
如果后续业务类型越来越多,多分支v-if判断过于冗余,可在父组件用动态组件+类型映射表简化代码,完全不需要改动网格组件:
// 父组件内定义类型与组件的映射关系 const componentMap = { dvd: DVD, cassette: Cassette // 新增类型直接在此处扩展 } export default { // 其他原有逻辑不变 computed: { componentMap: () => componentMap } }
父组件模板可简化为:
<MyUniversalComponent :items="items"> <template #default="{ item }"> <component :is="componentMap[item.type]" :data="item" /> </template> </MyUniversalComponent>
这种实现下网格组件完全不绑定任何业务逻辑,可适配渲染媒体封面、商品卡片、信息流条目等任意场景,不需要做任何定制修改。
内容的提问来源于stack exchange,提问作者user15909643
相关产品推荐
相关产品推荐

