直接复制js代码 看控制层数据即可
有很多优化的地方,只是提供一个思路
//========================================简单说明=============================================
/**
*
* 复制JS代码,直接看控制台打印信息
*
* 主要代码---> function mainX()
* function select(selectAttr)
* */
//========================================图文说明=============================================
//对应示意图
returnList1 = [
[ 2, 3, 0],
[ 2, 0, 3],
[ 2 ]
];
returnList2 =
[
[ 2, 3, 0],
[ 2, 0, 0],
[ 0 ]
];
/**
* returnList 相当于规格筛选结果
* 每次选择规格,数据都会变化,里面的数据相当于sku-Id
* "0"表示缺货
* */
//======================================数据部分=========================================
//商品sku信息(部分),主要关注参数productAttrName
let productSkuStock=[
{
"Id": 10,
"productId": 25,
"price": 99,
"stock": 99,
"pic": "/api/file/202102281351415352fc10e6453d95.png",
"productAttrName":"绿色8GB2000MA官方标配"
},
{
"Id": 11,
"productId": 25,
"price": 77,
"stock": 88,
"pic": "/api/file/2021022813515190522a64cc4bf6ba.png",
"productAttrName":"绿色8GB4000MA官方标配"
},
];
/**
* 模拟数据
* 查询出来的所有的 -> sku.productAttrName
* */
const Data = [
{Id:11,attr:'绿色6GB套餐一'},
{Id:12,attr:'白色6GB套餐一'},
{Id:13,attr:'白色8GB官方标配'},
{Id:14,attr:'白色8GB套餐二'},
];
//======================================规格部分=======================================
/**
* 规格
* 相当于产品sku所包含的所有规格(一层是一类)
* 从商品sku信息中,productAttrName参数中筛选摘录出来
*
* 怎样筛出所有规格数据,请看---> function getGuiGe()
* */
const guige = [
['绿色','白色'],
['8GB','6GB'],
['官方标配','套餐一','套餐二'],
];
/**
* 规格类别
* */
const Attr = ['颜色','版本','套餐'];
//======================================参数部分=======================================
//正则匹配次数 可忽略
var counts = 0;
/**
* 规格选择参数,与Attr规格类别对应
* */
const selectAttr = ['','',''];
//向页面展示数据
const ReturnList = [];
//======================================函数部分=======================================
/**
* 入口函数
* */
mainX();
function mainX(){
/**
* 主要选择函数(可绑定到所有的规格上)
*
* selectAttr相当于在页面中从上往下选择规格,一层层的筛选
* 依次带入将下列选择解开,并查看控制台
* (支持随机选取规格)
*/
//selectAttr[0] = '白色';
selectAttr[1] = '6GB';
//selectAttr[2] = '套餐一';
//可绑定到所有的规格上
select(selectAttr);
//========================展示筛选结果============================
/**
* ReturnList相当于筛选出来的结果
* 矩阵中 "0" 代表缺货
*/
console.log("---------返回矩阵---------");
console.log(ReturnList);
}
console.log("最终筛选的skuId---"+confirm());
function confirm() {
let name = '';
if(selectAttr.length == Attr.length){
for(let i = 0; i < selectAttr.length; i++){
name += selectAttr[i];
}
}
return selectName(name);
}
function selectName(name) {
for(let i = 0; i < Data.length; i++){
if(Data[i].attr.indexOf(name) >= 0){
return Data[i].Id;
}
}
return 0;
}
//主方法
function select(selectAttr){
//定义数组
for(let i = 0; i < guige.length;i++){
let arr = [];
for(let j = 0; j < guige[i].length;j++){
arr[j] = 0;
}
ReturnList.push(arr);
}
//规格行遍历
for(let i = 0; i < Attr.length; i++){
let arrayLevel = guige[i];
let selectAttrTemp = JSON.parse(JSON.stringify(selectAttr));//需要深克隆,赋值相当于指针指向该对象,修改会导致原数据改变
//开始吧颜色放入到所选规格
for(let k = 0; k < arrayLevel.length; k ++){
selectAttrTemp[i] = arrayLevel[k];
//把名称拼起来
let name = pinName(selectAttrTemp); //绿色+''+2000MA 短一个 用正则表达式 .+?8GB2000MA.+?
//开始正则索引
ReturnList[i][k] = reSelectName(name);
} // 获得 ReturnList[i]
selectAttrTemp = null;
}
return ReturnList;
}
//拼接正则名称
function pinName(array){
let name = '';
let exp = '.+?';
for(let i = 0; i < array.length; i++){
if(array[i] == null || array[i] == ''){
name +=exp;
}else{
//针对规格中的特殊符号的处理
name += array[i].replace(/([*.?+$^(){}|\\/])/g, '\\$1');
}
}
return name;
}
//正则查询名称
function reSelectName(name){
for(let i=0;i<Data.length;i++){
counts = counts + 1;
let reg = eval('/'+name+'/');
if(reg.exec(Data[i].attr)){
return Data[i].Id;
}
}
return 0;
}
//筛选规格函数
getGuiGe();
function getGuiGe(){
let sku = [
{
id:'10',
productName:'小米-lv',
productAttr:[
{key:"版本",value:"8GB"},
{key:"颜色",value:"绿色"},
{key:"套餐",value:"官方标配"},
],
productAttrName:"绿色8GB官方标配"
},
{
id:"10",
productName:"小米-lc",
productAttr:[
{key:"版本",value:"6GB"},
{key:"颜色",value:"白色"},
{key:"套餐",value:"官方标配"},
],
productAttrName:"白色6GB官方标配"
}
];
//实不相瞒,我数据库中的数据就是这样存的
//'productAttr':"[{'key':'版本','value':'全网通公开版 6+128GB'},{'key':'颜色','value':'白色'}]",
//'productAttrName':'白色6GB2000MA官方标配'
let arr=[];
//Attr 颜色','版本','容量','套餐
for(let j = 0; j < Attr.length; j++){
let arrc = [];
for(let i = 0; i < sku.length; i++){
let attrValue = sku[i].productAttr[j].value;
//匹配重复
if(arrc.length === 0)arrc.push(attrValue);
for(let k = 0; k < arrc.length; k++){
if(attrValue === arrc[k])
break;
if(k === arrc.length - 1)
arrc.push(attrValue);
}
}
arr[j] = arrc;
}
//查看筛选出来的规格即可
//console.log("arr--->");
//console.log(arr)
//Attr就是简单的把其中一个产品的key遍历出来就ok了
以上只是提供思路供大家参考
其中还有很多可以优化的地方,这里不做处理,还需要各位聪明的小伙伴发挥自己的聪明才智去优化
现在vue中很多类似组件可以直接拿来用,下面是vant的链接提供给大家,希望大家喜欢,也请大家用自己的小手手帮忙点点赞,谢谢!