库存不足规格必须实时禁用,每次点击后需用当前已选组合查询skuList,过滤stock>0的有效SKU并提取对应规格值;常见错误是直接渲染原始specs未动态过滤,导致显示不可用选项。

库存不足的规格项必须实时禁用,不能靠静态判断或缓存状态——每次点击后都要用当前已选规格组合去查 skuList,过滤出 stock > 0 的所有有效组合,再提取对应规格值。
为什么点完颜色后尺寸全灰了?
常见错误是把后端返回的原始 specs(如 ["红", "白", "黑"])直接渲染,没做动态过滤。比如实际只有 { spec_str: "红_S", stock: 10 } 和 { spec_str: "白_M", stock: 0 },但 UI 仍显示“白”可点、“M”可点,用户选完才发现没货。
- 后端返回的
skuList必须含specs数组字段(如["红色", "XL"]),不能只给skuCode或拼接字符串 - 不要用
spec_str.split("_")这类硬拆逻辑——规格名含下划线、中英文混用时会崩 - 真机上点击无反馈,大概率是没加
cursor: pointer,微信小程序原生组件不自动带手型
如何写 isSpecDisabled 过滤函数
这个函数不是查“有没有这个规格”,而是查“在当前已选条件下,选它能否组成至少一个有库存的 SKU”。它必须每次调用都遍历 skuList,不能缓存结果。
- 输入参数是
specName(如"颜色")和specValue(如"红色"),别传成"颜色_红色"字符串 - 内部逻辑:先筛选出所有满足
selectedValues的 SKU 子集,再检查这些 SKU 中是否存在specName === specValue的条目 - 示例:
isSpecDisabled(specName, specValue) { const matchedSkus = this.skuList.filter(sku => { return Object.keys(this.selectedValues).every(key => this.selectedValues[key] === sku.specs[this.specList.findIndex(s => s.name === key)] ) }) return !matchedSkus.some(sku => { const idx = this.specList.findIndex(s => s.name === specName) return sku.specs[idx] === specValue && sku.stock > 0 }) }
清空后续规格并重算禁用态的关键时机
用户改选前面的规格时,“后面选项为什么不更新”本质是响应式依赖断裂——selectedValues 更新了,但 computed 没立刻感知或没覆盖全部键。
- 不能分步操作:
this.selectedValues.color = "绿色"→this.$nextTick(() => this.updateDisabled()),因为$nextTick只等一次渲染,而updateDisabled里用的还是旧selectedValues快照 - 必须合并赋值:
this.$set(this, 'selectedValues', { ...this.selectedValues, color: "绿色" }),再立刻触发computed重新求值 - 点完“颜色”后,要删掉所有排在它后面的规格键:
Object.keys(this.selectedValues).forEach(key => { if (this.specList.findIndex(s => s.name === key) > currentIndex) this.$delete(this.selectedValues, key) })
最易被忽略的是:SKU 数据结构不统一。有的后端返回 specs: ["红", "XL"],有的返回 specs: { 颜色: "红", 尺寸: "XL" },还有的把规格值存在 properties 字段里——没做标准化预处理,isSpecDisabled 函数写得再对也白搭。


















