前端商品SKU筛选如何实现?

如何根据 sku_list 里面的 quantity 库存来改变 spec_list 里面的 disabled
判断他是否可以选择;其中 sku_list 里面的 keys_idsspec_list 里面的 spec_id 关联的

这个是不是要用到 笛卡尔积算法 ?

前端商品SKU筛选如何实现?

<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 来模拟

功能

  1. 被选中的显示为 【名称】
  2. 有库存的显示为  名称 
  3. 没库存的显示为  ---- 

输出

机型:【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'));


回答:

看不出来题主在纠结什么。

  1. 直接把两个数组合在一起,用来渲染
  2. 选择工具用 <input type="radio"> + <label>
  3. quantity 不够就 disabled

以上是 前端商品SKU筛选如何实现? 的全部内容, 来源链接: utcz.com/p/933048.html

回到顶部