结论:必须每次点击后基于已选规格和全量sku重算可用值,禁用逻辑不可缓存;spec_value_ids需后端返回结构化字段,前端禁止自行解析字符串;uni-app中须用computed生成响应式规格列表。

直接说结论:不能靠“点击一个、禁用一批”这种静态映射,必须每次点击后,基于当前已选规格 + 全量 skus 重算所有未选规格的可用值集合。否则必然出现“点完颜色,尺码全灰”或“选了S还能点L,最后提示无货”这类体验崩坏问题。
为什么 spec_value_ids 字符串格式必须和后端约定死
前端无法靠顺序推断组合含义。比如后端返回 spec_str: "red_S",你不能默认第一个是颜色、第二个是尺寸——万一将来加个“材质”字段,顺序一变就全乱。
- 强制要求后端返回结构化字段,如
spec_value_ids: ["color:red", "size:s"]或哈希字符串"color:red|size:s" - 拒绝解析
spec_str这种模糊字段:它没语义、不可扩展、不同类目拼接规则不一致 - 如果后端坚持只给
spec_str,必须明确约定分隔符(如_)和字段顺序,并在文档里写死:spec_str = color + "_" + size + "_" + material
点击规格时如何实时禁用无效选项
核心是“排除法”:先筛出所有包含当前已选条件的 skus,再从这些 skus 中提取其他规格的所有可能取值,其余值全部禁用。
- 假设已选
color:red,遍历所有skus,只保留spec_value_ids.includes("color:red")的项 - 对剩余
skus,收集size字段出现过的所有值(如["s", "m"]),这就是当前可选的尺码 - 把
specs中size对应的values数组,逐个标记disabled: !availableSizes.includes(value) -
uni-app中不能直接改原始specs数组元素的disabled属性——得用computed生成新数组,否则视图不更新
选中后怎么清空后续规格并联动更新价格/库存/图片
用户点完“红色”,再点“XL”,此时“尺寸”已确定,但“型号”还没选——那“型号”选项必须重置,不能残留上次选择。
- 用
Object.keys(this.selectedSpecs)获取已选规格名列表,找到当前点击规格的索引 - 遍历
this.selectedSpecs,把索引大于当前的规格全部this.$delete(this.selectedSpecs, name) - 价格/库存/图片必须从匹配的
sku中取:筛选条件是sku.spec_value_ids.every(id => this.selectedSpecs[id.split(':')[0]] === id.split(':')[1]) - 没完全选完时,价格显示“请选择规格”,库存显示“-”,图片保持主图——不要强行 fallback 到第一个 SKU
最容易被忽略的是:禁用逻辑必须在每次点击后完整重跑,而不是缓存中间状态;spec_value_ids 的解析必须和后端强约定,前端绝不自行拆解字符串;v-for 渲染的规格值列表,其 disabled 状态必须通过响应式计算生成,不能手动赋值。










