在加入购物车或者购买商品时,需要进行商品规格的选择,不同规格的组合会影响 库存、价格 等,还会因库存数量的不同判断是否可以购买。
实现类似的 规格组件 需要了解SKU和SPU两个概念。
SKU:标准化产品单元,即属性值、特性相同的商品就可以称为一个SPU。
SPU:库存量单位,即库存进出计量的单位, 可以是以件、盒、托盘等为单位。SKU是物理上不可分割的最小存货单元。在使用时要根据不同业态,不同管理模式来处理。
也就是:spu代表一个商品,拥有很多相同的属性。而sku代表该商品可选规格的任意组合,他是库存单位的唯一标识。
如何实现禁用效果:
大致步骤:
- 根据后台返回的skus数据得到有效sku组合
- 根据有效的sku组合得到所有的子集集合
- 根据子集集合组合成一个路径字典,也就是对象。
- 在组件初始化的时候去判断每个规格是否点击
- 在点击规格的时候去判断其他规格是否可点击
- 判断的依据是,拿着说有规格和现在已经选中的规则取搭配,得到可走路径。
- 如果可走路径在字典中,可点击
- 如果可走路径不在字典中,禁用
路径字典
通过 js算法库中的幂集算法,得到所有sku组合子集
js算法库 https://github.com/trekhleb/javascript-algorithms
import getPowerSet from '@/vender/power-set'
const spliter = '★'
// 根据skus数据得到路径字典对象
const getPathMap = (skus) => {
const pathMap = {}
skus.forEach(sku => {
// 1. 过滤出有库存有效的sku
if (sku.inventory) {
// 2. 得到sku属性值数组
const specs = sku.specs.map(spec => spec.valueName)
// 3. 得到sku属性值数组的子集
const powerSet = getPowerSet(specs)
// 4. 设置给路径字典对象
powerSet.forEach(set => {
const key = set.join(spliter)
if (pathMap[key]) {
// 已经有key往数组追加
pathMap[key].push(sku.id)
} else {
// 没有key设置一个数组
pathMap[key] = [sku.id]
}
})
}
})
return pathMap
}
上面的★是自定义拼接字符
示例:
设置状态
大致的步骤:
- 再需要更新状态的时候获取当前选中的规格数组
- 遍历所有的规格按钮,拿出按钮的值设置给规格数组,让后得到key
- 拿着key去路径字典中查找,有就可点击,没有禁用即可。
具体代码参考项目地址:https://gitee.com/mmsmd/eribbit-client-pc.git