前端商品SKU筛选如何实现?
如何根据 sku_list
里面的 quantity
库存来改变 spec_list
里面的 disabled
判断他是否可以选择;其中 sku_list
里面的 keys_ids
和 spec_list
里面的 spec_id
关联的
这个是不是要用到 笛卡尔积算法 ?
<template> <div v-for="(item, index) in spec_list" :key="index" class="main">
<p>{{item.title}}</p>
<p>
<spen v-for="(item2, index2) in item.children" :key="index2" :class="['main-item', {'active': item2.active, 'disabled': item2.disabled}]" @click="clickSpec(index, index2)">{{item2.title}}</spen>
</p>
</div>
<div class="main" v-if="sku">{{sku}}</div>
</template>
<script>
import {computed, reactive} from "vue";
export default {
setup() {
const spec_list = reactive([{
"title": "机型",
"active": false,
"disabled": false,
"spec_id": "107",
"parent_id": "0",
"children": [{
"title": "iPhone 14",
"active": false,
"disabled": false,
"spec_id": "109",
"parent_id": "107"
}, {
"title": "iPhone 14 Plus",
"active": false,
"disabled": false,
"spec_id": "110",
"parent_id": "107"
}]
}, {
"title": "颜色",
"active": false,
"disabled": false,
"spec_id": "108",
"parent_id": "0",
"children": [{
"title": "蓝色",
"active": false,
"disabled": false,
"spec_id": "111",
"parent_id": "108"
}, {
"title": "紫色",
"active": false,
"disabled": false,
"spec_id": "112",
"parent_id": "108"
}, {
"title": "午夜色",
"active": false,
"disabled": false,
"spec_id": "113",
"parent_id": "108"
}, {
"title": "星光色",
"active": false,
"disabled": false,
"spec_id": "114",
"parent_id": "108"
}, {
"title": "红色",
"active": false,
"disabled": false,
"spec_id": "115",
"parent_id": "108"
}]
}, {
"title": "存储容量",
"active": false,
"disabled": false,
"spec_id": "116",
"parent_id": "0",
"children": [{
"title": "128GB",
"active": false,
"disabled": false,
"spec_id": "117",
"parent_id": "116"
}, {
"title": "256GB",
"active": false,
"disabled": false,
"spec_id": "118",
"parent_id": "116"
}, {
"title": "512GB",
"active": false,
"disabled": false,
"spec_id": "119",
"parent_id": "116"
}]
}]);
const sku_list = reactive([{
"quantity": "0",
"sku_id": "195",
"keys_ids": "107:109;108:111;116:117",
}, {
"quantity": "100",
"sku_id": "196",
"keys_ids": "107:109;108:112;116:117",
}, {
"quantity": "0",
"sku_id": "197",
"keys_ids": "107:109;108:113;116:117",
}, {
"quantity": "100",
"sku_id": "198",
"keys_ids": "107:109;108:114;116:117",
}, {
"quantity": "100",
"sku_id": "199",
"keys_ids": "107:109;108:115;116:117",
}, {
"quantity": "100",
"sku_id": "200",
"keys_ids": "107:110;108:111;116:117",
}, {
"quantity": "100",
"sku_id": "201",
"keys_ids": "107:110;108:112;116:117",
}, {
"quantity": "100",
"sku_id": "202",
"keys_ids": "107:110;108:113;116:117",
}, {
"quantity": "100",
"sku_id": "203",
"keys_ids": "107:110;108:114;116:117",
}, {
"quantity": "100",
"sku_id": "204",
"keys_ids": "107:110;108:115;116:117",
}, {
"quantity": "100",
"sku_id": "205",
"keys_ids": "107:109;108:111;116:118",
}, {
"quantity": "100",
"sku_id": "206",
"keys_ids": "107:109;108:112;116:118",
}, {
"quantity": "100",
"sku_id": "207",
"keys_ids": "107:109;108:113;116:118",
}, {
"quantity": "100",
"sku_id": "208",
"keys_ids": "107:109;108:114;116:118",
}, {
"quantity": "100",
"sku_id": "209",
"keys_ids": "107:109;108:115;116:118",
}, {
"quantity": "100",
"sku_id": "210",
"keys_ids": "107:110;108:111;116:118",
}, {
"quantity": "100",
"sku_id": "211",
"keys_ids": "107:110;108:112;116:118",
}, {
"quantity": "100",
"sku_id": "212",
"keys_ids": "107:110;108:113;116:118",
}, {
"quantity": "100",
"sku_id": "213",
"keys_ids": "107:110;108:114;116:118",
}, {
"quantity": "100",
"sku_id": "214",
"keys_ids": "107:110;108:115;116:118",
}, {
"quantity": "100",
"sku_id": "215",
"keys_ids": "107:109;108:111;116:119",
}, {
"quantity": "100",
"sku_id": "216",
"keys_ids": "107:109;108:112;116:119",
}, {
"quantity": "100",
"sku_id": "217",
"keys_ids": "107:109;108:113;116:119",
}, {
"quantity": "100",
"sku_id": "218",
"keys_ids": "107:109;108:114;116:119",
}, {
"quantity": "100",
"sku_id": "219",
"keys_ids": "107:109;108:115;116:119",
}, {
"quantity": "100",
"sku_id": "220",
"keys_ids": "107:110;108:111;116:119",
}, {
"quantity": "100",
"sku_id": "221",
"keys_ids": "107:110;108:112;116:119",
}, {
"quantity": "100",
"sku_id": "222",
"keys_ids": "107:110;108:113;116:119",
}, {
"quantity": "100",
"sku_id": "223",
"keys_ids": "107:110;108:114;116:119",
}, {
"quantity": "100",
"sku_id": "224",
"keys_ids": "107:110;108:115;116:119",
}]);
const sku = computed(function () {
const keys_ids = [];
spec_list.forEach(function(val) {
val.children.forEach(function(val2) {
if (val2.active) {
keys_ids.push(val.spec_id + ':' + val2.spec_id);
}
});
});
return sku_list.find(o => o.keys_ids == keys_ids.join(';'));
});
const clickSpec = (index, index2) => {
spec_list[index].children.forEach(function(val, i) {
val.active = (!val.disabled && i == index2);
});
}
return {spec_list, sku_list, sku, clickSpec}
}
}
</script>
<style>
#preloader-active {
display: none;
}
.main {
width: 500px;
margin: 30px auto;
}
.main-item {
border: #ddd 1px solid;
padding: 5px 10px;
margin: 5px;
display: inline-block;
cursor: pointer;
}
.main-item:hover {
border: #ef0909 1px solid;
}
.main-item.active {
border: #ef0909 1px solid;
}
.main-item.disabled {
border: #ddd 1px dashed;
}
.main-item.disabled:hover {
border: #ddd 1px dashed;
}
</style>
https://sfc.vuejs.org/#eNrFWk...
一个朋友用库存的方法,解决了这个问题,备注一下:
https://sfc.vuejs.org/#eNrFWs...
<template> <div v-for="(item, index) in spec_list" :key="index" class="main">
<p>{{item.title}}</p>
<p>
<spen v-for="(item2, index2) in item.children" :key="index2" :class="['main-item', {'active': item2.active, 'disabled': !countQuantity(item, item2)}]" @click="clickSpec(index, index2)">{{item2.title}}:{{countQuantity(item, item2)}}</spen>
</p>
</div>
<div class="main" v-if="sku">{{sku}}</div>
</template>
<script>
import {computed, reactive} from "vue";
export default {
name: "TestView",
setup() {
const spec_list = reactive([{
"title": "机型",
"active": false,
"disabled": false,
"spec_id": "107",
"parent_id": "0",
"children": [{
"title": "iPhone 14",
"active": false,
"disabled": false,
"spec_id": "109",
"parent_id": "107"
}, {
"title": "iPhone 14 Plus",
"active": false,
"disabled": false,
"spec_id": "110",
"parent_id": "107"
}]
}, {
"title": "颜色",
"active": false,
"disabled": false,
"spec_id": "108",
"parent_id": "0",
"children": [{
"title": "蓝色",
"active": false,
"disabled": false,
"spec_id": "111",
"parent_id": "108"
}, {
"title": "紫色",
"active": false,
"disabled": false,
"spec_id": "112",
"parent_id": "108"
}, {
"title": "午夜色",
"active": false,
"disabled": false,
"spec_id": "113",
"parent_id": "108"
}, {
"title": "星光色",
"active": false,
"disabled": false,
"spec_id": "114",
"parent_id": "108"
}, {
"title": "红色",
"active": false,
"disabled": false,
"spec_id": "115",
"parent_id": "108"
}]
}, {
"title": "存储容量",
"active": false,
"disabled": false,
"spec_id": "116",
"parent_id": "0",
"children": [{
"title": "128GB",
"active": false,
"disabled": false,
"spec_id": "117",
"parent_id": "116"
}, {
"title": "256GB",
"active": false,
"disabled": false,
"spec_id": "118",
"parent_id": "116"
}, {
"title": "512GB",
"active": false,
"disabled": false,
"spec_id": "119",
"parent_id": "116"
}]
}]);
const sku_list = reactive([{
"quantity": "0",
"sku_id": "195",
"keys_ids": "107:109;108:111;116:117",
}, {
"quantity": "100",
"sku_id": "196",
"keys_ids": "107:109;108:112;116:117",
}, {
"quantity": "0",
"sku_id": "197",
"keys_ids": "107:109;108:113;116:117",
}, {
"quantity": "100",
"sku_id": "198",
"keys_ids": "107:109;108:114;116:117",
}, {
"quantity": "100",
"sku_id": "199",
"keys_ids": "107:109;108:115;116:117",
}, {
"quantity": "100",
"sku_id": "200",
"keys_ids": "107:110;108:111;116:117",
}, {
"quantity": "100",
"sku_id": "201",
"keys_ids": "107:110;108:112;116:117",
}, {
"quantity": "100",
"sku_id": "202",
"keys_ids": "107:110;108:113;116:117",
}, {
"quantity": "100",
"sku_id": "203",
"keys_ids": "107:110;108:114;116:117",
}, {
"quantity": "100",
"sku_id": "204",
"keys_ids": "107:110;108:115;116:117",
}, {
"quantity": "100",
"sku_id": "205",
"keys_ids": "107:109;108:111;116:118",
}, {
"quantity": "100",
"sku_id": "206",
"keys_ids": "107:109;108:112;116:118",
}, {
"quantity": "100",
"sku_id": "207",
"keys_ids": "107:109;108:113;116:118",
}, {
"quantity": "100",
"sku_id": "208",
"keys_ids": "107:109;108:114;116:118",
}, {
"quantity": "100",
"sku_id": "209",
"keys_ids": "107:109;108:115;116:118",
}, {
"quantity": "100",
"sku_id": "210",
"keys_ids": "107:110;108:111;116:118",
}, {
"quantity": "100",
"sku_id": "211",
"keys_ids": "107:110;108:112;116:118",
}, {
"quantity": "100",
"sku_id": "212",
"keys_ids": "107:110;108:113;116:118",
}, {
"quantity": "100",
"sku_id": "213",
"keys_ids": "107:110;108:114;116:118",
}, {
"quantity": "100",
"sku_id": "214",
"keys_ids": "107:110;108:115;116:118",
}, {
"quantity": "100",
"sku_id": "215",
"keys_ids": "107:109;108:111;116:119",
}, {
"quantity": "100",
"sku_id": "216",
"keys_ids": "107:109;108:112;116:119",
}, {
"quantity": "100",
"sku_id": "217",
"keys_ids": "107:109;108:113;116:119",
}, {
"quantity": "100",
"sku_id": "218",
"keys_ids": "107:109;108:114;116:119",
}, {
"quantity": "100",
"sku_id": "219",
"keys_ids": "107:109;108:115;116:119",
}, {
"quantity": "100",
"sku_id": "220",
"keys_ids": "107:110;108:111;116:119",
}, {
"quantity": "100",
"sku_id": "221",
"keys_ids": "107:110;108:112;116:119",
}, {
"quantity": "100",
"sku_id": "222",
"keys_ids": "107:110;108:113;116:119",
}, {
"quantity": "100",
"sku_id": "223",
"keys_ids": "107:110;108:114;116:119",
}, {
"quantity": "100",
"sku_id": "224",
"keys_ids": "107:110;108:115;116:119",
}]);
const active = {}
const sku = computed(function () {
const keys_ids = [];
spec_list.forEach(function(val) {
val.children.forEach(function(val2) {
if (val2.active) {
keys_ids.push(val.spec_id + ':' + val2.spec_id);
}
});
});
return sku_list.find(o => o.keys_ids == keys_ids.join(';'));
});
const clickSpec = (index, index2) => {
spec_list[index].children.forEach(function(val, i) {
val.active = (!val.disabled && i == index2);
});
const item1 = spec_list[index];
const item2 = item1.children[index2];
active[item1.spec_id]=item2.spec_id;
}
const countQuantity = (item1, item2) => {
const active2 = {...active, [item1.spec_id]:item2.spec_id}
return sku_list.filter(sku=>{
return spec_list.every(spec => {
const id1 = spec.spec_id
const id2 = active2[id1]
if (id2)return sku.keys_ids.split(';').includes([id1, id2].join(':'));
return true
})
}).reduce((r,sku)=>r+Number(sku.quantity), 0)
}
return {spec_list, sku_list, sku, clickSpec, countQuantity}
}
}
</script>
<style>
#preloader-active {
display: none;
}
.main {
width: 500px;
margin: 30px auto;
}
.main-item {
border: #ddd 1px solid;
padding: 5px 10px;
margin: 5px;
display: inline-block;
cursor: pointer;
}
.main-item:hover {
border: #ef0909 1px solid;
}
.main-item.active {
border: #ef0909 1px solid;
}
.main-item.disabled {
border: #ddd 1px dashed;
}
.main-item.disabled:hover {
border: #ddd 1px dashed;
}
</style>
@无名 老大改的答案
https://sfc.vuejs.org/#__DEV_...
<template> <div v-for="(item, index) in spec_list" :key="index" class="main">
<p>{{item.title}}</p>
<p>
<span v-for="(item2, index2) in item.children" :key="index2" :class="['main-item', {'active': active[item.spec_id] == item2.spec_id, 'disabled': !isSpecEnabled(item, item2)}]" @click="clickSpec(item, item2)">{{item2.title}}:{{countQuantity(item, item2)}}</span>
</p>
</div>
<!-- <div class="main" v-if="sku">{{sku}}</div> -->
</template>
<script>
import {computed, reactive} from "vue";
export default {
setup() {
const spec_list = [{
"title": "机型",
"active": false,
"disabled": false,
"spec_id": "107",
"parent_id": "0",
"children": [{
"title": "iPhone 14",
"active": false,
"disabled": false,
"spec_id": "109",
"parent_id": "107"
}, {
"title": "iPhone 14 Plus",
"active": false,
"disabled": false,
"spec_id": "110",
"parent_id": "107"
}]
}, {
"title": "颜色",
"active": false,
"disabled": false,
"spec_id": "108",
"parent_id": "0",
"children": [{
"title": "蓝色",
"active": false,
"disabled": false,
"spec_id": "111",
"parent_id": "108"
}, {
"title": "紫色",
"active": false,
"disabled": false,
"spec_id": "112",
"parent_id": "108"
}, {
"title": "午夜色",
"active": false,
"disabled": false,
"spec_id": "113",
"parent_id": "108"
}, {
"title": "星光色",
"active": false,
"disabled": false,
"spec_id": "114",
"parent_id": "108"
}, {
"title": "红色",
"active": false,
"disabled": false,
"spec_id": "115",
"parent_id": "108"
}]
}, {
"title": "存储容量",
"active": false,
"disabled": false,
"spec_id": "116",
"parent_id": "0",
"children": [{
"title": "128GB",
"active": false,
"disabled": false,
"spec_id": "117",
"parent_id": "116"
}, {
"title": "256GB",
"active": false,
"disabled": false,
"spec_id": "118",
"parent_id": "116"
}, {
"title": "512GB",
"active": false,
"disabled": false,
"spec_id": "119",
"parent_id": "116"
}]
}];
const sku_list = [{
"quantity": "0",
"sku_id": "195",
"keys_ids": "107:109;108:111;116:117",
}, {
"quantity": "100",
"sku_id": "196",
"keys_ids": "107:109;108:112;116:117",
}, {
"quantity": "0",
"sku_id": "197",
"keys_ids": "107:109;108:113;116:117",
}, {
"quantity": "100",
"sku_id": "198",
"keys_ids": "107:109;108:114;116:117",
}, {
"quantity": "100",
"sku_id": "199",
"keys_ids": "107:109;108:115;116:117",
}, {
"quantity": "100",
"sku_id": "200",
"keys_ids": "107:110;108:111;116:117",
}, {
"quantity": "100",
"sku_id": "201",
"keys_ids": "107:110;108:112;116:117",
}, {
"quantity": "100",
"sku_id": "202",
"keys_ids": "107:110;108:113;116:117",
}, {
"quantity": "100",
"sku_id": "203",
"keys_ids": "107:110;108:114;116:117",
}, {
"quantity": "100",
"sku_id": "204",
"keys_ids": "107:110;108:115;116:117",
}, {
"quantity": "100",
"sku_id": "205",
"keys_ids": "107:109;108:111;116:118",
}, {
"quantity": "100",
"sku_id": "206",
"keys_ids": "107:109;108:112;116:118",
}, {
"quantity": "100",
"sku_id": "207",
"keys_ids": "107:109;108:113;116:118",
}, {
"quantity": "100",
"sku_id": "208",
"keys_ids": "107:109;108:114;116:118",
}, {
"quantity": "100",
"sku_id": "209",
"keys_ids": "107:109;108:115;116:118",
}, {
"quantity": "100",
"sku_id": "210",
"keys_ids": "107:110;108:111;116:118",
}, {
"quantity": "100",
"sku_id": "211",
"keys_ids": "107:110;108:112;116:118",
}, {
"quantity": "100",
"sku_id": "212",
"keys_ids": "107:110;108:113;116:118",
}, {
"quantity": "100",
"sku_id": "213",
"keys_ids": "107:110;108:114;116:118",
}, {
"quantity": "100",
"sku_id": "214",
"keys_ids": "107:110;108:115;116:118",
}, {
"quantity": "100",
"sku_id": "215",
"keys_ids": "107:109;108:111;116:119",
}, {
"quantity": "100",
"sku_id": "216",
"keys_ids": "107:109;108:112;116:119",
}, {
"quantity": "100",
"sku_id": "217",
"keys_ids": "107:109;108:113;116:119",
}, {
"quantity": "100",
"sku_id": "218",
"keys_ids": "107:109;108:114;116:119",
}, {
"quantity": "100",
"sku_id": "219",
"keys_ids": "107:109;108:115;116:119",
}, {
"quantity": "100",
"sku_id": "220",
"keys_ids": "107:110;108:111;116:119",
}, {
"quantity": "100",
"sku_id": "221",
"keys_ids": "107:110;108:112;116:119",
}, {
"quantity": "100",
"sku_id": "222",
"keys_ids": "107:110;108:113;116:119",
}, {
"quantity": "100",
"sku_id": "223",
"keys_ids": "107:110;108:114;116:119",
}, {
"quantity": "100",
"sku_id": "224",
"keys_ids": "107:110;108:115;116:119",
}];
// 为了保证生成正则时的顺序,只能提前生成 {机型: null, 颜色: null, 容量: null} 了
let active = reactive(Object.fromEntries(spec_list.map(i => [i.spec_id, null])));
const clickSpec = ({spec_id: id1}, {spec_id: id2}) => {
if (active[id1] != id2)
active[id1] = id2;
else
active[id1] = null;
};
const isSpecEnabled = ({spec_id: id1}, {spec_id: id2}) => {
return sku_list.filter(sku => sku.quantity > 0).some(sku => {
const pattern = Object.entries(active).map(([k, v]) => k == id1 ? `${k}:${id2}` : v ? `${k}:${v}` : '.*').join(';');
return sku.keys_ids.match(new RegExp('^' + pattern + '$'));
})
};
const countQuantity = (item1, item2) => {
const active2 = {...active, [item1.spec_id]: item2.spec_id}
return sku_list.filter(sku => {
const sku_keys_ids_array = sku.keys_ids.split(';');
return spec_list.every(spec => {
const id1 = spec.spec_id;
const id2 = active2[id1];
if (id2) return sku_keys_ids_array.includes([id1, id2].join(':'));
return true
})
}).reduce((r, sku) => r + Number(sku.quantity), 0)
};
return {spec_list, sku_list, active, clickSpec, isSpecEnabled, countQuantity};
}
}
</script>
<style>
.main {
width: 500px;
margin: 30px auto;
}
.main-item {
border: #ddd 1px solid;
padding: 5px 10px;
margin: 5px;
display: inline-block;
cursor: pointer;
}
.main-item:hover {
border: #ef0909 1px solid;
}
.main-item.active {
border: #ef0909 1px solid;
}
.main-item.disabled {
border: #ddd 1px dashed;
}
.main-item.disabled:hover {
border: #ddd 1px dashed;
}
</style>
回答:
前端新手来参与讨论。
感觉可用正则来确定是否有库存。
没有 vue.js
,写了段 js
来模拟
功能
- 被选中的显示为
【名称】
- 有库存的显示为
名称
- 没库存的显示为
----
输出
机型:【iPhone 14】 iPhone 14 Plus 颜色:【蓝色】 紫色 午夜色 星光色 红色
存储容量: ----- 【256GB】 512GB
js
代码
chosen = {107: 109, 108: 111, 116: 118};console.log(spec_list.map(i =>
i.title + ':' + i.children.map(j =>
(chosen[i.spec_id] == j.spec_id ? '【-】' : ' - ').replace('-', sku_list.some(sku =>
sku.keys_ids.match(new RegExp('^' + Object.entries(chosen).map(([k, v]) => k == i.spec_id ? `${k}:${j.spec_id}` : (v != null ? `${k}:${v}` : '.*')).join(';') + '$')) && sku.quantity > 0) ? j.title : '-'.repeat(j.title.length)
)
).join('')
).join('\n'));
回答:
看不出来题主在纠结什么。
- 直接把两个数组合在一起,用来渲染
- 选择工具用
<input type="radio">
+<label>
quantity
不够就disabled
以上是 前端商品SKU筛选如何实现? 的全部内容, 来源链接: utcz.com/p/933048.html