商品 规格 动态选择 参数 js

直接复制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的链接提供给大家,希望大家喜欢,也请大家用自己的小手手帮忙点点赞,谢谢!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值