preface

Recently, the company’s project needs to develop a points mall, which involves skU inventory selection. I thought it was not difficult, but I encountered great problems in the development. Now I have recorded the implementation logic, the idea may not be the best, but it is also a solution for other partners to learn from. Have better scheme can leave a message to discuss learning together.

What is the sku

Sku: Inventory holding unit refers to the unit of inventory in and out measurement, which can be in units of pieces, boxes, pallets, etc. The SKU is the smallest unit of inventory that is physically indivisible. In use according to different formats, different management mode to deal with. It is most commonly used in clothing and footwear.

The effect of the final realization

Overall implementation idea

  1. The interface gets a list of existing inventory and a list of SKU specification attributes (pit: inventory may have a specification missing, so the most complete specification attributes should be obtained by the interface, not by rendering inventory)
  2. The SKU specification attribute list is compared to the inventory list, graying options that do not have inventory
  3. Click on a specific property to make it selected or deselect it
  4. Loop through the list of specification attributes, setting Disabled to true, then take each of all specification attributes and compare them with each of the selected data to form a new comparison, compare them with the existing inventory, find the existing clickable items, and set disable to false

Text description is too boring, give chestnuts to fill the stomach:

For the sake of subsequent description, let’s remember three data: 1. Inventory list, 2. Specification attribute list, 3. Select the list.

Assume that the existing inventory list is:

[
    "Small, green,one"."Small, green,two"."Small, green,three"."Medium, green,one"."Middle, green,two"."Middle, green,three"."Big, green,two"."Big, green,three"."Big, orange,three"
]
Copy the code

2. Specifications attribute list

[{"id": "547f76222d4d4f92a49de2e0bf6bd7ef"."type": 1,
      "name": "Color"."propertyList": [{"id": "8ed34030c93c4dc29e43edb95e6cfca2"."property": 1,
          "name": "Orange"
        },
        {
          "id": "c80cbe4c6cbf49f5b2822331768cd422"."property": 2."name": "Green"}]}, {"id": "21967fba6b574b479974e50720ad25fe"."type": 2."name": "Test Category"."propertyList": [{"id": "f40c3884e5e9422c973d31631a65ae64"."property": 1,
          "name": "Small"
        },
        {
          "id": "edac997ed2c54e41b1f3076fbd6e19f9"."property": 2."name": "In"
        },
        {
          "id": "408fb530344a4a41b33932431638dcbb"."property": 3."name": "Big"}]}, {"id": "fe7f49a798794670be622e6b9d2f386a"."type": 3."name": "tester"."propertyList": [{"id": "c76dc797eaae4d8eb360de8811a9ec7a"."property": 1,
          "name": "one"
        },
        {
          "id": "02808ac287e8410f936a90167d82ee2b"."property": 2."name": "two"
        },
        {
          "id": "d5660085ff8743d999f6ed3a497ec8b7"."property": 3."name": "three"}}]]Copy the code

3. Selected arrays

See the GIF above for the rendered interface.

When the ‘orange’ in the color is clicked, the orange becomes selected, and each item in the loop specification attribute list is combined with the selected ‘orange’ to create a new data. Set disable to true for the current loop item and then compare it to the existing inventory list. If this combination exists, Sets the disable attribute of the current loop to false. If the selected item contains the same group of data during the loop, it replaces the same group of data in the selected array with the current loop property, compares the new data to the inventory, and sets disable.

Now the selected array is [‘ orange ‘], the loop size attribute list [‘ orange ‘, ‘green’, ‘small’, ‘middle’, ‘large’, ‘one’, ‘two’, ‘three’], the first ‘orange’ belongs to the same group as the ‘orange’ of the selected array, so replacing the ‘orange’ of the selected array to form a new array is still [‘ orange ‘], Take the new array [‘ orange ‘] inventory list to find if ‘orange’ exists, there are oranges in inventory, so ‘orange’ can be clicked; Next is the second ‘green ‘,’ green’ is the same as’ orange ‘in the selected array, according to the above logic, the new array is [‘ green ‘], take [‘ green ‘] to check the inventory, also exists, so’ green ‘can also be clicked; [‘ small ‘,’ orange ‘] = ‘small ‘,’ orange ‘] =’ small ‘,’ orange ‘=’ small ‘; The rest and so on…

The code after the project is cleaned up

The layout style

<template>
  <div>
    <div class="content fix-header fix-bottom"> <! --> <div class="mask">
        <div class="mask-content">
          <div class="mask-title">
            <div class="mask-close iconfont-shop icon-close"></div> Select the specification parameter </div> <div class="spec-items">
            <div class="spec-menu-item js-spec-menu" v-for="(item, index) in goodsTypeList" :key="item.id">
              <div class="spec-note">{{item.name}}</div>
              <div class="spec-choices">
                <span v-for="(el, i) in item.propertyList"
                      :key="el.id"
                      :class="{'active' : el.selected, 'disabled': el.disabled}"
                      @click="handleClickSpecs1(item.id, el.id, el, index, i)"
                >{{el.name}}</span>
              </div>
            </div>
            <div class="spec-menu-item">
              <div class="spec-note"> quantity </div> <div class="spec-num">
                <span class="minus">-</span>
                <input type="number" v-model="buyNumber" maxlength="3"/>
                <span class="add">+</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
Copy the code

Logical processing

<script>
  let orgdata = {
    "skus": [{"id": "f5eee18b8d5b4fc2b46a56e92abdb525"."stockAmmount": 7,
        "isPaymentAccpoints": 1,
        "isPaymentCurrency": 0."isPaymentMixed": 0."priceAccpoints": 1,
        "priceCurrency": 0."mixedPriceAccpoints": 0."mixedPriceCurrency": 0."rebate": 100,
        "skusTypes": [{"id": "74fe546803e44a7c95bebfe56a29952d"."typeId": "21967fba6b574b479974e50720ad25fe"."typeName": "Test Category"."type": 2."propertyId": "f40c3884e5e9422c973d31631a65ae64"."propertyName": "Small"."property": 1}, {"id": "78f98ee53ae549ceb2c18629152ff849"."typeId": "fe7f49a798794670be622e6b9d2f386a"."typeName": "tester"."type": 3."propertyId": "02808ac287e8410f936a90167d82ee2b"."propertyName": "two"."property": 2}, {"id": "91cefe600f40498bb5013deebb9c27be"."typeId": "547f76222d4d4f92a49de2e0bf6bd7ef"."typeName": "Color"."type": 1,
            "propertyId": "c80cbe4c6cbf49f5b2822331768cd422"."propertyName": "Green"."property": 2}]}, {"id": "383feb7947f14ce5b832bc8700e65c9e"."stockAmmount": 2."isPaymentAccpoints": 1,
        "isPaymentCurrency": 0."isPaymentMixed": 0."priceAccpoints": 1,
        "priceCurrency": 0."mixedPriceAccpoints": 0."mixedPriceCurrency": 0."rebate": 100,
        "skusTypes": [{"id": "1beed60c2eb244f89ad82806d343d468"."typeId": "fe7f49a798794670be622e6b9d2f386a"."typeName": "tester"."type": 3."propertyId": "02808ac287e8410f936a90167d82ee2b"."propertyName": "two"."property": 2}, {"id": "357fd7db1f5244e5b64f48a34bb581fa"."typeId": "21967fba6b574b479974e50720ad25fe"."typeName": "Test Category"."type": 2."propertyId": "edac997ed2c54e41b1f3076fbd6e19f9"."propertyName": "In"."property": 2}, {"id": "5c29a251e55a4b678fc4f8287cc560b5"."typeId": "547f76222d4d4f92a49de2e0bf6bd7ef"."typeName": "Color"."type": 1,
            "propertyId": "c80cbe4c6cbf49f5b2822331768cd422"."propertyName": "Green"."property": 2}]}, {"id": "905b10e1740e4be992d14cfc23a887a2"."stockAmmount": 4."isPaymentAccpoints": 1,
        "isPaymentCurrency": 0."isPaymentMixed": 0."priceAccpoints": 1,
        "priceCurrency": 0."mixedPriceAccpoints": 0."mixedPriceCurrency": 0."rebate": 100,
        "skusTypes": [{"id": "0a5f93d9ef1c486ba369dcb1fbd3aed9"."typeId": "fe7f49a798794670be622e6b9d2f386a"."typeName": "tester"."type": 3."propertyId": "c76dc797eaae4d8eb360de8811a9ec7a"."propertyName": "one"."property": 1}, {"id": "d920730c34644218b3d0bbc5fca5edf4"."typeId": "21967fba6b574b479974e50720ad25fe"."typeName": "Test Category"."type": 2."propertyId": "f40c3884e5e9422c973d31631a65ae64"."propertyName": "Small"."property": 1}, {"id": "2afbe8a77d034de0a1655f9ad1a25b95"."typeId": "547f76222d4d4f92a49de2e0bf6bd7ef"."typeName": "Color"."type": 1,
            "propertyId": "c80cbe4c6cbf49f5b2822331768cd422"."propertyName": "Green"."property": 2}]}, {"id": "a440b0084e564d3e9d7c8b445bb7645e"."stockAmmount": 10,
        "isPaymentAccpoints": 1,
        "isPaymentCurrency": 0."isPaymentMixed": 0."priceAccpoints": 1,
        "priceCurrency": 0."mixedPriceAccpoints": 0."mixedPriceCurrency": 0."rebate": 100,
        "skusTypes": [{"id": "12a4715b6730438888e88f302871245a"."typeId": "21967fba6b574b479974e50720ad25fe"."typeName": "Test Category"."type": 2."propertyId": "f40c3884e5e9422c973d31631a65ae64"."propertyName": "Small"."property": 1}, {"id": "9063e1f1586f4a74b2f614039e8743c4"."typeId": "547f76222d4d4f92a49de2e0bf6bd7ef"."typeName": "Color"."type": 1,
            "propertyId": "c80cbe4c6cbf49f5b2822331768cd422"."propertyName": "Green"."property": 2}, {"id": "ae38b9cf56d5408a809d6fbd1b902ee5"."typeId": "fe7f49a798794670be622e6b9d2f386a"."typeName": "tester"."type": 3."propertyId": "d5660085ff8743d999f6ed3a497ec8b7"."propertyName": "three"."property": 3}]}, {"id": "9961364cc3494823aaf7699733393335"."stockAmmount": 15."isPaymentAccpoints": 1,
        "isPaymentCurrency": 0."isPaymentMixed": 0."priceAccpoints": 1,
        "priceCurrency": 0."mixedPriceAccpoints": 0."mixedPriceCurrency": 0."rebate": 100,
        "skusTypes": [{"id": "3335920f79914cfb8a39ae22b0802bc0"."typeId": "fe7f49a798794670be622e6b9d2f386a"."typeName": "tester"."type": 3."propertyId": "c76dc797eaae4d8eb360de8811a9ec7a"."propertyName": "one"."property": 1}, {"id": "34950de7059d4fffac485abb59a79381"."typeId": "21967fba6b574b479974e50720ad25fe"."typeName": "Test Category"."type": 2."propertyId": "edac997ed2c54e41b1f3076fbd6e19f9"."propertyName": "In"."property": 2}, {"id": "a82ff8d74d3d4a1ea454e4870cc68b64"."typeId": "547f76222d4d4f92a49de2e0bf6bd7ef"."typeName": "Color"."type": 1,
            "propertyId": "c80cbe4c6cbf49f5b2822331768cd422"."propertyName": "Green"."property": 2}]}, {"id": "bd3aeb3c7c854a80b88e7f82a5a78a1e"."stockAmmount": 8,
        "isPaymentAccpoints": 1,
        "isPaymentCurrency": 0."isPaymentMixed": 0."priceAccpoints": 1,
        "priceCurrency": 0."mixedPriceAccpoints": 0."mixedPriceCurrency": 0."rebate": 100,
        "skusTypes": [{"id": "4fc8e61aa192463085578de92974b18b"."typeId": "21967fba6b574b479974e50720ad25fe"."typeName": "Test Category"."type": 2."propertyId": "edac997ed2c54e41b1f3076fbd6e19f9"."propertyName": "In"."property": 2}, {"id": "884f32b64a4b478bb01f93b40dfeb6fc"."typeId": "547f76222d4d4f92a49de2e0bf6bd7ef"."typeName": "Color"."type": 1,
            "propertyId": "c80cbe4c6cbf49f5b2822331768cd422"."propertyName": "Green"."property": 2}, {"id": "f66109eccd934529a18026376fccfa7b"."typeId": "fe7f49a798794670be622e6b9d2f386a"."typeName": "tester"."type": 3."propertyId": "d5660085ff8743d999f6ed3a497ec8b7"."propertyName": "three"."property": 3}]}, {"id": "5e094973bbaf41ce81b7b626174b0bbf"."stockAmmount": 8,
        "isPaymentAccpoints": 1,
        "isPaymentCurrency": 0."isPaymentMixed": 0."priceAccpoints": 1,
        "priceCurrency": 0."mixedPriceAccpoints": 0."mixedPriceCurrency": 0."rebate": 100,
        "skusTypes": [{"id": "23d688678aaa42eebd3c04cceaa61bac"."typeId": "547f76222d4d4f92a49de2e0bf6bd7ef"."typeName": "Color"."type": 1,
            "propertyId": "8ed34030c93c4dc29e43edb95e6cfca2"."propertyName": "Orange"."property": 1}, {"id": "55649f0753464921b68b0017ce0010d7"."typeId": "21967fba6b574b479974e50720ad25fe"."typeName": "Test Category"."type": 2."propertyId": "408fb530344a4a41b33932431638dcbb"."propertyName": "Big"."property": 3}, {"id": "d7248b12b7e847ca9be024ed3bb6d101"."typeId": "fe7f49a798794670be622e6b9d2f386a"."typeName": "tester"."type": 3."propertyId": "d5660085ff8743d999f6ed3a497ec8b7"."propertyName": "three"."property": 3}]}, {"id": "60ce0a1f99e940dc82d041d36681111b"."stockAmmount": 9,
        "isPaymentAccpoints": 1,
        "isPaymentCurrency": 0."isPaymentMixed": 0."priceAccpoints": 1,
        "priceCurrency": 0."mixedPriceAccpoints": 0."mixedPriceCurrency": 0."rebate": 100,
        "skusTypes": [{"id": "91faddf91e944cabadbda5c342430139"."typeId": "547f76222d4d4f92a49de2e0bf6bd7ef"."typeName": "Color"."type": 1,
            "propertyId": "c80cbe4c6cbf49f5b2822331768cd422"."propertyName": "Green"."property": 2}, {"id": "207698d97e4247bb9747843d16e25750"."typeId": "21967fba6b574b479974e50720ad25fe"."typeName": "Test Category"."type": 2."propertyId": "408fb530344a4a41b33932431638dcbb"."propertyName": "Big"."property": 3}, {"id": "3c69d3c73aa24cccbacaf805d71117fd"."typeId": "fe7f49a798794670be622e6b9d2f386a"."typeName": "tester"."type": 3."propertyId": "d5660085ff8743d999f6ed3a497ec8b7"."propertyName": "three"."property": 3}]}, {"id": "f3c805d1959d413a86679955ae047ec5"."stockAmmount": 10,
        "isPaymentAccpoints": 1,
        "isPaymentCurrency": 0."isPaymentMixed": 0."priceAccpoints": 1,
        "priceCurrency": 0."mixedPriceAccpoints": 0."mixedPriceCurrency": 0."rebate": 100,
        "skusTypes": [{"id": "00113d4b6046411cb8ff935b2743904b"."typeId": "fe7f49a798794670be622e6b9d2f386a"."typeName": "tester"."type": 3."propertyId": "02808ac287e8410f936a90167d82ee2b"."propertyName": "two"."property": 2}, {"id": "c13d8a4c7a18477fbe7027044d0393a0"."typeId": "547f76222d4d4f92a49de2e0bf6bd7ef"."typeName": "Color"."type": 1,
            "propertyId": "c80cbe4c6cbf49f5b2822331768cd422"."propertyName": "Green"."property": 2}, {"id": "653d0e243bab45eaa5c83dc8206ee33e"."typeId": "21967fba6b574b479974e50720ad25fe"."typeName": "Test Category"."type": 2."propertyId": "408fb530344a4a41b33932431638dcbb"."propertyName": "Big"."property": 3}]}]};let goodType = [
    {
      "id": "547f76222d4d4f92a49de2e0bf6bd7ef"."type": 1,
      "name": "Color"."propertyList": [{"id": "8ed34030c93c4dc29e43edb95e6cfca2"."property": 1,
          "name": "Orange"
        },
        {
          "id": "c80cbe4c6cbf49f5b2822331768cd422"."property": 2."name": "Green"}]}, {"id": "21967fba6b574b479974e50720ad25fe"."type": 2."name": "Test Category"."propertyList": [{"id": "f40c3884e5e9422c973d31631a65ae64"."property": 1,
          "name": "Small"
        },
        {
          "id": "edac997ed2c54e41b1f3076fbd6e19f9"."property": 2."name": "In"
        },
        {
          "id": "408fb530344a4a41b33932431638dcbb"."property": 3."name": "Big"}]}, {"id": "fe7f49a798794670be622e6b9d2f386a"."type": 3."name": "tester"."propertyList": [{"id": "c76dc797eaae4d8eb360de8811a9ec7a"."property": 1,
          "name": "one"
        },
        {
          "id": "02808ac287e8410f936a90167d82ee2b"."property": 2."name": "two"
        },
        {
          "id": "d5660085ff8743d999f6ed3a497ec8b7"."property": 3."name": "three"}}]]export default {
    name: "Detail".data() {
      return {
        maskVisible: true, skuList: [], lastCheckedSku: {}, // buyNumber: 1, // buyNumber: null, currentSkuList: [], valueIdSortAndIndex: [], goodsTypeList: [], selectItemList: [] } },mounted() { this.init(); This.getshopgoodstype () this.initGoodType()}, methods: {init() {
        let valueIdSortAndIndex = [];
        let currentSkuList = orgdata.skus.map((item,index) => {
          letvalueIdSort = []; item.skusTypes.map(skusTypesItem=>{ valueIdSort.push(skusTypesItem.propertyId) }); Valueidsortandindex. push({valueIdSort: sku/valueidSortAndIndex. push({valueIdSort: sku/valueidSortAndIndex. push({valueIdSort: sku/valueidSortAndIndex. push({valueIdSort: sku/valueidSortAndIndex. push({valueIdSort: sku/valueidSortAndIndex. push({valueIdSort: sku/valueidSortAndIndex. push(); valueIdSort.sort()})return item.skusTypes
        });

        this.$set(this.$data.'currentSkuList', currentSkuList);
        this.$set(this.$data.'valueIdSortAndIndex', valueIdSortAndIndex); }, isContained(aa, bb) {// Check whether the aa array contains all bb arraysif(! (aa instanceof Array) ||! (bb instanceof Array) ||(aa.length<bb.length) ){return false;
        }
        let aaStr = aa.toString();
        for(var i=0; i<bb.length; i++){if(aaStr.indexOf(bb[i])<0){
            return false; }}return true; }, // Get all specificationsgetShopGoodsType() {/ / goodType for interface data returned goodType. ForEach (items = > {items. PropertyList. ForEach (item = > {item. Selected =false;
            item.disabled = true; }) }) this.goodsTypeList = goodType; }, // Initialize whether there is inventoryinitGoodType() {let currentSkuList = this.currentSkuList.flat(Infinity);
        this.goodsTypeList.forEach(items=>{
          items.propertyList.forEach(item=>{
            for(var i=0; i<currentSkuList.length; i++){
              if (item.id == currentSkuList[i].propertyId) {
                item.disabled = false;
                break; HandleClickSpecs1 (grounpId, ID, EL, index, I){letselectItemList = this.selectItemList; // Selected specificationsif (el.disabled) {
          return; } // Handle the logic of selectedif(! el.selected) { this.goodsTypeList[index].propertyList.forEach(item=>{ item.selected =false;
          })
          this.goodsTypeList[index].propertyList[i].selected = true; ForEach ((item, x_selected_index) => {forEach((item, x_selected_index) => {if (item.index === index) {
              selectItemList.splice(x_selected_index, 1)
            }
          });
          selectItemList.push({grounpId, id, index, i});
        } elseThis.goodstypelist [index]. PropertyList [I]. Selected =false;
          selectItemList.forEach((item, x_selected_index) => {
            if(item.id === id && item.grounpId === grounpId) { selectItemList.splice(x_selected_index, 1); }}); } this.$set(this.$data.'selectItemList', selectItemList) // Select group IDletx_selected_grounpIds = []; selectItemList.forEach(item=>{ x_selected_grounpIds.push(item.grounpId); }); // Process the logic of disabledif(selectitemList.length == 0) {// Select null and re-initialize data this.initGoodType(); }else{// Take each item of the goodsTypeList with each item of the selected data (selectItemList) to form a comparison item. Find the existence of this clickable item. GoodsTypeList. ForEach ((goodsType goodsTypeIndex) = > {goodsType. PropertyList. ForEach ((prop, propIndex) = > {if(! prop.selected) { prop.disabled =true; } // This loop datalet push_data = {grounpId: goodsType.id, id: prop.id, index: goodsTypeIndex, i: propIndex}
              if(x_selected_groundbids.indexof (goodsType. Id) > -1){// Group ID of the current loop specification in the selected specification, delete the same group specification, replace with the current specification and compare with the inventoryletsel = selectItemList.slice(); // Accept data with a new variable to prevent modification of source datalet index_splice = x_selected_grounpIds.indexOf(goodsType.id);
                sel.splice(index_splice, 1, push_data);
                this.optionsHandle(sel, push_data)
              } else{// The current cycle size group ID is not in the selected size, add the current size to the copied selected array, loop comparisonlet sel = selectItemList.slice();
                sel.push(push_data);
                this.optionsHandle(sel, push_data)
              }
            })
          })
        }
      },
      optionsHandle(selArr, push_data){
        letSelarr.map (item=>{propertyids.push (item.id)}); selarr.map (item=>{propertyids.push (item.id)}); / / if there is a option to look for in the existing inventory, optional into clickable enclosing valueIdSortAndIndex. The map (item = > {if (this.isContained(item.valueIdSort, propertyIds)){
            this.goodsTypeList[push_data.index].propertyList[push_data.i].disabled = false; }}); }}}; </script>Copy the code

conclusion

When you encounter problems, you need to communicate more. You are welcome to write better solutions in the comments section. 521 oh!