vue实现商品多规格
Vue 实现商品多规格功能
数据结构设计
商品多规格通常需要嵌套数据结构,常见方案是使用skus和specs的组合。例如:
data() {
return {
product: {
specs: [
{
name: '颜色',
values: ['红色', '黑色', '金色']
},
{
name: '内存',
values: ['64G', '128G', '256G']
}
],
skus: [
{
specValues: ['红色', '64G'],
price: 5999,
stock: 100
},
// 其他SKU组合...
]
}
}
}
规格选择交互
使用v-for渲染规格选项,并通过计算属性处理选中状态:

<div v-for="spec in product.specs" :key="spec.name">
<h3>{{ spec.name }}</h3>
<button
v-for="value in spec.values"
:key="value"
@click="selectSpec(spec.name, value)"
:class="{ active: isSelected(spec.name, value) }"
>
{{ value }}
</button>
</div>
状态管理逻辑
通过selectedSpecs对象记录当前选择,并实时计算可用SKU:

methods: {
selectSpec(specName, value) {
this.$set(this.selectedSpecs, specName, value)
},
isSelected(specName, value) {
return this.selectedSpecs[specName] === value
}
},
computed: {
availableSkus() {
return this.product.skus.filter(sku => {
return Object.entries(this.selectedSpecs).every(
([specName, value]) => sku.specValues.includes(value)
)
})
}
}
库存与价格联动
根据当前选择的规格组合显示对应信息:
<div v-if="currentSku">
<p>价格: {{ currentSku.price }}</p>
<p>库存: {{ currentSku.stock }}</p>
</div>
computed: {
currentSku() {
return this.availableSkus.find(sku =>
sku.specValues.length === Object.values(this.selectedSpecs).length
)
}
}
禁用不可选规格
通过计算属性实现规格的禁用状态:
computed: {
isDisabled() {
return (specName, value) => {
const tempSelected = {...this.selectedSpecs, [specName]: value}
return !this.product.skus.some(sku =>
Object.entries(tempSelected).every(
([name, val]) => sku.specValues.includes(val)
)
)
}
}
}
完整组件示例
<template>
<div class="spec-container">
<!-- 规格选择区域 -->
<div v-for="spec in product.specs" :key="spec.name">
<h3>{{ spec.name }}</h3>
<button
v-for="value in spec.values"
:key="value"
@click="selectSpec(spec.name, value)"
:class="{
active: isSelected(spec.name, value),
disabled: isDisabled(spec.name, value)
}"
:disabled="isDisabled(spec.name, value)"
>
{{ value }}
</button>
</div>
<!-- 商品信息展示 -->
<div v-if="currentSku" class="sku-info">
<p>已选择: {{ Object.values(selectedSpecs).join(' + ') }}</p>
<p>价格: ¥{{ currentSku.price }}</p>
<p>库存: {{ currentSku.stock }}件</p>
</div>
</div>
</template>






