如何在Vue.js通用组件中展示两类不同结构的数组对象数据
现有代码问题先修正
你提供的listData生成逻辑里有几处可先修正的问题:
- 循环内的判断条件
data.skuId === null应该改为item.skuId === null,当前取的是外层data对象的skuId,无法正确判断每个子项的类型 priceProduct: item.price后缺少逗号,会触发语法错误- 当前方法返回的
dataList是对象结构,但你给出的结果示例是数组,若用于列表渲染建议调整为数组结构,将每一项push到数组中返回
优化方案
你现在的多v-if写法能跑通,但维护性较低,后续如果新增商品类型,模板里的判断逻辑会越来越臃肿,推荐按自己的业务场景选择以下优化方案:
方案1:父层统一字段结构(最推荐)
在生成listData的时候就把两类对象的字段对齐,不需要子组件感知数据类型,从根源消除模板判断逻辑:
listData() { let dataCode = Object.entries(this.data); let dataList = []; // 调整为数组适配列表渲染 for (let [id, item] of dataCode) { const baseItem = { id: item.skuId || favoris.id, price: item.skuId === null ? item.price : item.sellPriceCustomer, name: item.skuId === null ? item.name : '', size: item.skuId === null ? '' : item.attributes.size, type: item.skuId === null ? 'product' : 'sku' } dataList.push(baseItem); } return dataList; }
子组件模板直接使用统一字段即可,判断逻辑简化为字段是否存在:
<span v-if="item.name" class="text-bold">{{ item.name }}</span> <span v-if="item.size"> size: {{ item.size }}</span> <span class="text-bold">{{ item.price }} €</span>
方案2:子层用计算属性收拢逻辑
如果不想修改父层的数据处理逻辑,可以把模板里的判断挪到计算属性中,避免模板里充斥大量业务逻辑:
// 子组件计算属性 computed: { displayContent() { if (this.skuId !== null) { return { name: '', size: this.size, price: this.priceSku } } return { name: this.name, size: '', price: this.priceProduct } } }
模板直接读取计算属性返回值即可:
<span v-if="displayContent.name" class="text-bold">{{ displayContent.name }}</span> <span v-if="displayContent.size"> size: {{ displayContent.size }}</span> <span class="text-bold">{{ displayContent.price }} €</span>
方案3:动态组件拆分(适合多类型拓展场景)
如果后续还会新增更多商品类型,建议按类型拆分成独立的小组件,子组件用component动态加载对应类型的展示组件,完全消除判断逻辑:
<!-- 父组件调用通用子组件时传入类型 --> <CommonItem :item="item" :type="item.skuId ? 'sku' : 'product'" /> <!-- 通用子组件内动态加载对应组件 --> <component :is="`${type}-item`" :item="item" />
内容的提问来源于stack exchange,提问作者francky
相关产品推荐
相关产品推荐

