小程序多规格商品

1、数据结构 (后台提供的)

goodsBaseInfo: {
      // 单个商品
      goodsId: "",
       "skuNameList":[
         // 最多三个,最少一个;
       {//规格名称
          "id":"3333",//id
          "name":"颜色",//名字
         //"specificationName": [
           //{"value":"白色"},
           //{"value":"黑色"},
          //{"value":"灰灰色"},
         //]
        },
      ],
       "skuList":[
        {//规格名称
          "id":"123456",//id
          "specification": '[{"id":"3333", "value":"白色"},{"id":"4444","value":"XL"},{"id":"5555","value":"河南"}]', // 规格内容
         "price":"120",//价格
         "stock":"10"//库存
        },
     ],
    },

data 中定义

modelTypeLists: [], // 规格类型列表
selectArr: [], //存放被选中的值
shopItemInfo: {}, //存放要和选中的值进行匹配的数据
subIndex: [], //是否选中 因为不确定是多规格还是单规格,所以这里定义数组来判断

2、首先需要将数据格式进行转换,(规格名称拼接为对应的键)

rewriteDataFormat() {
// 从后台拿到数据之后,进行数据处理
    let that = this;
    // 将规格名称格式转换为键值对;  
    let { skuNameList, resDataSkuList } = that.data;
    // let skuNameList = skuNameList;
    // let resDataSkuList = resDataSkuList;
    let skuList = [];
    let shopItemInfo = {}
     
    resDataSkuList.map((item, index) => {
      item['specification'] = JSON.parse(item.specification);
      let itemKey = '';
      item['specification'].map((i, i_j) => {
        i['isShow'] = true;
        // 属性名拼接
        itemKey = itemKey + ',' +  i.value;
        // console.log('itemKey:', itemKey);
      })
      // 去掉属性名拼接中第一个逗号
      let reg = new RegExp(",","");
      let a = itemKey.replace(reg,"");
      // console.log('itemKey reg:', a);
      shopItemInfo[a] = item;
      skuList.push(item);
    });
    console.log('skuList:', skuList);
    console.log('shopItemInfo:', shopItemInfo);

    that.setData({ shopItemInfo});
    console.log('skuNameList:', skuNameList);
    // 组装,规格名称
    skuNameList.map((it, indx) => {
      var specificationName = [];
      skuList.map((ite, ind) => {
        ite.specification.map((j, ind_j) => {
          if (it.id === j.id) {
            let valueName = j.value;
            specificationName.push(valueName);
          }
        })
      });
      // 去重
      specificationName = [...new Set(specificationName)];
      let newSpecificationNameArr =  []
      specificationName.map((item, index) =>{
        let a = {'value': item};
        newSpecificationNameArr.push(a); 
      })
      it['specificationName'] = newSpecificationNameArr;
    });
    console.log('skuNameList:', skuNameList);
    that.setData({
      modelTypeLists: skuNameList,
      // baseSkuNameList: skuNameList,
    })
  },

其中:shopItemInfo很重要:
得到如:

shopItemInfo: {
   "灰色,NL,南京":{
      id: "29f9ca54e3b442608194cdad00a7b9ca",
      price: 6,
      specification: [
        {id: "bafc8e356361449c85dfc44bbe7204f0", value: "灰色", isShow: true},
        {id: "00eecd2b3bc946afb5a7bfb7d5a510f4", value: "NL", isShow: true},
        {id: "a4cbb3513e884e99ac3dcbb0c8fcc622", value: "南京", isShow: true}],
      stock: 99
    },
    "灰色,NL,东郡":{
      id: "29f9ca54e3b442608194cdad00a7b9ca",
      price: 6,
      specification: [
        {id: "bafc8e356361449c85dfc44bbe7204f0", value: "灰色", isShow: true},
        {id: "00eecd2b3bc946afb5a7bfb7d5a510f4", value: "NL", isShow: true},
        {id: "a4cbb3513e884e99ac3dcbb0c8fcc622", value: "东郡", isShow: true}],
      stock: 99
    }
  }

得到skuNameList
如下:

skuNameList:[
  {
    id: "bafc8e356361449c85dfc44bbe7204f0",
    name: "颜色",
    specificationName: [
      {value: "灰色"},
      {value: "白色"}
    ]
  },
  {
    id: "bafc8e356361449c85dfc44bbe7204f0",
    name: "产地",
    specificationName: [
      {value: "南京"},
      {value: "东郡"}
    ]
  },
  {
    id: "bafc8e356361449c85dfc44bbe7204f0",
    name: "尺寸",
    specificationName: [
      {value: "ML"},
      {value: "XL"}
    ]
  }
]

3、小程序DOM结构

<view class="pop_lists"> 
 <view class="sku_item" wx:for="{{modelTypeLists}}" wx:key="id" wx:for-index="idx" wx:for-item="i">
    <view class="pop_lists_name">{{i.name}}</view>
    <view class="pop_item">
      <view wx:for="{{i.specificationName}}" wx:for-index="idxj" wx:for-item="j" wx:key="_idxj"  data-value="{{j.value}}" data-index="{{idxj}}" data-parent-index="{{idx}}" bindtap="chouseModelType"  class="pop_li {{subIndex[idx] === idxj ? 'cur_chouse' : ''}}{{j.isShow ?  'disabled': ''}}">
        {{j.value}}
      </view>
    </view>
  </view>
</view>

4、chooseModelType事件处理

chooseModelType(event) {
   let that = this;
   console.log('event:', event)
   let eventData = event.currentTarget.dataset;
   let value = eventData.value;
   let curIndex = eventData.index;
   let curIndexParent = eventData.parentIndex;
   let {selectArr, subIndex} = that.data;
   if (selectArr[curIndexParent] != value) {
     selectArr[curIndexParent] = value;
     subIndex[curIndexParent] = curIndex;
   } else {
     selectArr[curIndexParent] = "";
     subIndex[curIndexParent] = -1; //去掉选中的颜色
   }
   console.log('selectArr:', selectArr);
   console.log('subIndex:', subIndex);
   that.setData({
     selectArr,
     subIndex
   })
   
   that.checkItem()
 },

判断选中的规格中是否有对应的库存量

checkItem: function () {
    var that = this;
    let {selectArr, subIndex,  modelTypeLists, shopItemInfo} = that.data;
    var option = modelTypeLists;
    var result = []; //定义数组储存被选中的值
    for(var i in option){
      result[i] = selectArr[i] ? selectArr[i] : '';
    }
    for (var i in option) {
      var last = result[i]; //把选中的值存放到字符串last去
      // 关键处理
      for (var k in option[i].specificationName) {
        result[i] = option[i].specificationName[k].value; //赋值,存在直接覆盖,不存在往里面添加name值
        option[i].specificationName[k]['isShow'] = that.isStocks(result); //在数据里面添加字段isShow来判断是否可以选择
      }
      result[i] = last; //还原,目的是记录点下去那个值,避免下一次执行循环时被覆盖
    }
    // 更新数据
    that.setData({
      modelTypeLists:option
    })
	// 匹配到对应的规格信息
    if (shopItemInfo[result]) {
      that.setData({
        modelTypePrice: shopItemInfo[result].price || '0',
        modelTypeStock: shopItemInfo[result].stock,
        modelTypeName: result,
      })
      // 存储规格名
      shopItemInfo[result]['modelTypeName'] = result;
      that.setData({
        modelType: shopItemInfo[result]
      })
    } 
  },
  isStocks: function (result) {
  	// 关键所在 判断是否可以选择规格
    let that = this;
    let { shopItemInfo } = that.data;
    for (var i in result) {
      if (result[i] == '') {
        return false; //如果数组里有为空的值,那直接返回true
      }
    }
    return shopItemInfo[result].stock == 0 ? true : false //匹配选中的数据的库存,若不为空返回true反之返回false
  },

关键是自己组装数据,根据对象的键(key)值,匹配到对应的value;
效果如下图:
在这里插入图片描述
欢迎优化批评;
1、明确后台提供的数据结构;
2、优化重组数据,以适合前端使用;
3、根据逐一并且是按顺序保存选中的规格名称;
4、根据选中的规格名称匹配对应规格的库存量,若库存量0,则对应的规格是无法选择的,以及价格;
5、更多项目可以查看 github地址;若找不到为私密项目,可以加QQ:982701105
劳动不易感谢鼓励
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刺客-Andy

努力将爱好变成更有价值的事物

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值