个人理解,有问题或者更好的方法欢迎一起探讨
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>前端SKU实现</title>
</head>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<body>
<div id="app">
<h3>前端SKU实现</h3>
<div v-for="(item,index) in specList" :key="index">
<div class='title'>{{item.title}}</div>
<div class='spec'>
<div class='spec-item' v-for="(its,ins) in item.list" :key="its.name + ins">
<span @click="changeSpec(item.title, its.name, its.able)"
:class="[selectSpec[item.title] === its.name ? 'active' : '' , its.able? '' : 'disabled']">{{its.name}}</span>
</div>
</div>
</div>
</div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
specList: [
{ title: "颜色", list: ["红色", "紫色", "白色", "黑色"] },
{ title: "套餐", list: ["套餐一", "套餐二", "套餐三", "套餐四"] },
{ title: "内存", list: ["64G", "128G", "256G"] }
],
skuList: [
// { id: 1608188117177, specs: ["红色", "套餐一", "64G"] },
{ id: 1608188117178, specs: ["红色", "套餐一", "128G"] },
{ id: 1608188117179, specs: ["红色", "套餐一", "256G"] },
{ id: 1608188117180, specs: ["红色", "套餐二", "64G"] },
{ id: 1608188117181, specs: ["红色", "套餐二", "128G"] },
{ id: 1608188117182, specs: ["红色", "套餐二", "256G"] },
{ id: 1608188117183, specs: ["红色", "套餐三", "64G"] },
{ id: 1608188117184, specs: ["红色", "套餐三", "128G"] },
{ id: 1608188117185, specs: ["红色", "套餐三", "256G"] },
// { id: 1608188117186, specs: ["红色", "套餐四", "64G"] },
// { id: 1608188117187, specs: ["红色", "套餐四", "128G"] },
// { id: 1608188117188, specs: ["红色", "套餐四", "256G"] },
// { id: 1608188117189, specs: ["紫色", "套餐一", "64G"] },
// { id: 1608188117190, specs: ["紫色", "套餐一", "128G"] },
// { id: 1608188117191, specs: ["紫色", "套餐一", "256G"] },
{ id: 1608188117192, specs: ["紫色", "套餐二", "64G"] },
{ id: 1608188117193, specs: ["紫色", "套餐二", "128G"] },
{ id: 1608188117194, specs: ["紫色", "套餐二", "256G"] },
{ id: 1608188117195, specs: ["紫色", "套餐三", "64G"] },
{ id: 1608188117196, specs: ["紫色", "套餐三", "128G"] },
{ id: 1608188117197, specs: ["紫色", "套餐三", "256G"] },
{ id: 1608188117198, specs: ["紫色", "套餐四", "64G"] },
{ id: 1608188117199, specs: ["紫色", "套餐四", "128G"] },
{ id: 1608188117200, specs: ["紫色", "套餐四", "256G"] },
{ id: 1608188117201, specs: ["白色", "套餐一", "64G"] },
{ id: 1608188117202, specs: ["白色", "套餐一", "128G"] },
{ id: 1608188117203, specs: ["白色", "套餐一", "256G"] },
{ id: 1608188117204, specs: ["白色", "套餐二", "64G"] },
// { id: 1608188117205, specs: ["白色", "套餐二", "128G"] },
// { id: 1608188117206, specs: ["白色", "套餐二", "256G"] },
// { id: 1608188117207, specs: ["白色", "套餐三", "64G"] },
// { id: 1608188117208, specs: ["白色", "套餐三", "128G"] },
// { id: 1608188117209, specs: ["白色", "套餐三", "256G"] },
// { id: 1608188117210, specs: ["白色", "套餐四", "64G"] },
{ id: 1608188117211, specs: ["白色", "套餐四", "128G"] },
{ id: 1608188117212, specs: ["白色", "套餐四", "256G"] },
// { id: 1608188117213, specs: ["黑色", "套餐一", "64G"] },
// { id: 1608188117214, specs: ["黑色", "套餐一", "128G"] },
// { id: 1608188117215, specs: ["黑色", "套餐一", "256G"] },
// { id: 1608188117216, specs: ["黑色", "套餐二", "64G"] },
// { id: 1608188117217, specs: ["黑色", "套餐二", "128G"] },
// { id: 1608188117218, specs: ["黑色", "套餐二", "256G"] },
// { id: 1608188117219, specs: ["黑色", "套餐三", "64G"] },
// { id: 1608188117220, specs: ["黑色", "套餐三", "128G"] },
// { id: 1608188117221, specs: ["黑色", "套餐三", "256G"] },
// { id: 1608188117222, specs: ["黑色", "套餐四", "64G"] },
// { id: 1608188117223, specs: ["黑色", "套餐四", "128G"] },
// { id: 1608188117224, specs: ["黑色", "套餐四", "256G"] }
],
selectSpec: {},
},
created() {
// 初始化选择数据的对象
// this.specList.forEach(item => {
// this.$set(this.selectSpec, item.title, "");
// })
this.selectSpec = {
'颜色': '',
'套餐': '套餐一',
'内存': '64G'
}
// 将规格数据处理成我们视图所需要的数据类型
this.specList = this.specList.map(item => {
return {
title: item.title,
list: item.list.map(its => {
return {
name: its,
// 判断是否可以选择
// 这里相当于init 初始化数据 this.isAble() 核心判断逻辑
able: this.isAble(item.title, its) // 注释的调试看逻辑代码 false
}
})
}
})
// 注释的调试看逻辑代码
// this.selectSpec = {
// '颜色':'',
// '套餐':'套餐一',
// '内存':'64G'
// }
// this.isAble('颜色', '红色')
},
methods: {
// 核心判断逻辑
// 判断规格是否可以被选择 核心函数 key当前的规格的title value规格值
// '颜色', '红色'
isAble(key, value) { //此时 key = 颜色 value = 红色
var copySelectSpec = JSON.parse(JSON.stringify(this.selectSpec));
// 赋值当前选择项
copySelectSpec[key] = value; // 此时 copySelectSpec = {"颜色":"红色","套餐":"套餐一","内存":"64G"}
let flag = this.skuList.some(item => {
// 按照上面的skuList数据 此时第一次循环 item = { id: 1608188117178, specs: ["红色", "套餐一", "128G"] }
var i = 0;
// copySelectSpec去匹配item.specs
/* {"颜色":"红色","套餐":"套餐一","内存":"64G"} 匹配 ["红色", "套餐一", "128G"]
如果选了 套餐一和64G 的情况下 结果i=2;证明此项不可选择*/
for (let k in copySelectSpec) { // for in 懂吧?
// copySelectSpec[k] 判断第一个标签是否可选的时候(红色),依次是 '红色' \ '套餐一' \ '64G'
if (copySelectSpec[k] != "" && item.specs.includes(copySelectSpec[k])) { // item中有红色 i++
i++
} else if (copySelectSpec[k] == "") { // ''后面规格是空字符串 不管 也执行 i++(""为没有选择当前项)
i++;
}
}
console.log(this.specList.length, i)
// 此时 红色满足条件 return true 此时红色规格校验完毕 并会退出当选skuList循环
//
return i == this.specList.length
})
return flag
},
// 点击事件
changeSpec(key, value, able) {
if (!able) return
if (this.selectSpec[key] === value) {
this.selectSpec[key] = ''
} else {
this.selectSpec[key] = value
}
// forEach循环改变原数组
this.specList.forEach(item => {
item.list.forEach(its => {
its.able = this.isAble(item.title, its.name);
});
});
}
}
})
</script>
<style>
.spec-item {
display: inline-block;
margin-right: 10px;
}
.spec-item span {
border: 1px solid #eee;
cursor: pointer;
padding: 5px 10px;
}
.spec-item .active {
border: 1px solid red;
background-color: red;
color: #fff;
}
.spec-item .disabled {
color: #c0c4cc;
cursor: not-allowed;
background-image: none;
background-color: #fff;
border-color: #ebeef5;
}
</style>
</html>
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。