前端实现SKU
思路
声明一个对象,存储选择属性。
必须给每一个属性值添加一个是否可选,必须循环每一条sku 与 选择属性判断。
点击一次必定会循环每一个属性值做判断,这一步不能省略。可以参考代码。
ps:不要使用矩阵(亲身经历)
使用矩阵会导致点击两次以上时,存在 sku中没有的属性值也能选择的情况。
created() {
// 处理数据
this.skuList = skuList;
// 初始化选择数据的对象
attrList.forEach(item => {
this.$set(this.selectAttr, item.title, "");
})
// 将规格数据处理成我们视图所需要的数据类型
this.attrList = attrList.map(item => {
return {
title:item.title,
//将具体属性值 做修改,给每一个 单独的值添加一个able
list: item.list.map(its => {
return {
name:its,
// 判断是否可以选择
able: this.isAble(item.title, its) // 注释的调试看逻辑代码 false
}
})
}
})
console.log(JSON.stringify(this.selectAttr))
},
methods:{
// 判断规格是否可以被选择 核心函数 key当前的规格的title value规格值
isAble(key, value){
// 深拷贝 避免被影响 当前选择的属性值
var copyselectAttr = JSON.parse(JSON.stringify(this.selectAttr));
// 用对象的好处就在这了 直接赋值当前验证项
copyselectAttr[key] = value;
// 用数组的 some 方法 效率高 符合条件直接退出循环
let flag = this.skuList.some(item => {
// 条件判断 核心逻辑判断
// console.log(item)
var i = 0 ;
// 这个for in 循环的逻辑就对底子不深的人来说就看不懂了 原理就是循环已经选中的 和 正在当前对比的数据 和 所有的sku对比 只有当前验证的所有项满足sku中的规格或者其他规格为空时 即满足条件 稍微有点复杂 把注释的调试代码打开就调试下就可以看懂了
// debugger
for(let k in copyselectAttr) { //三个属性 分别与 sku集合做对比
console.log("深拷贝:"+k,copyselectAttr[k]);
// console.log(copyselectAttr[k]) // 注释的调试看逻辑代码
if(copyselectAttr[k] != "" && item.sku.includes(copyselectAttr[k])){ //将sku 和所有可选择属性值做对比 如果某个sku包含这个属性值 则i++
i++
}else if (copyselectAttr[k] == "") { //如果不包含 再判断当前 循环的可选属性值 是否为空
i++;
}
}
// 符合下面条件就退出了 不符合会一直循环知道循环结束没有符合的条件就 return false 了
return i == attrList.length //当 三个属性判断完
})
return flag
},
// 点击事件
changeSpec(key,value,able){
if(!able) return
//点击一个已选择的属性值
if(this.selectAttr[key] === value){
this.selectAttr[key] = ''
}else {
this.selectAttr[key] = value
}
// forEach循环改变原数组
this.attrList.forEach(item => { //循环所有属性
item.list.forEach(its => { //循环所有属性值
its.able = this.isAble(item.title, its.name); //重新给每一个属性值 的able(可选) 赋值
console.log(its.name, its.able);
});
});
}
},
代码提供 : 掘金
源代码 : gitHub:前端商品sku-demo