結合element-ui表格自動生成sku規格列表

最近在寫一個根據輸入的規格,屬性值動態生成sku表格,實現的效果大體如圖,這是在vue項目裏,結合element-UI表格寫的,寫好了就整理了一下,把代碼貼上來,方便之後使用,不過代碼裏仍是有一些重複的東西沒整理,由於急着完成功能,也沒太注意代碼整潔,之後有時間再整理一下vue

讀取規格列表的功能是,若是你此次存了一個表格給後臺,查看詳情時,後臺返回給你,你須要把它渲染到頁面上用的,我這裏寫的比較複雜,由於用v-model綁定input,取值的時候要用對象取法,因此存進去的時候也是用的對象存放數組

若是你只是要實現動態生成規格表的話,有這段代碼就好了,能夠生成3*2*2的組合app

/**
* 遞歸生成規格列表
* @param {*} skuarr 存儲每一種排列組合的數組
* @param {*} i 要用list數據的第幾項做爲基數,i爲幾,最後的結果就是以list[i]的數據開頭,通常以第一項的值放在組合的第一位,若是要以其餘屬性開頭,方法須要變更一下,有興趣能夠本身研究
* @param {*} list 要生成排列的原始數據
*/
var arr = []
function func(skuarr= [], i, list){  
for (let j=0; j<list[i].length; j++) { if (i<list.length-1) {    // 演示一下第一次執行函數的結果 skuarr[i] = list[i][j] // skuarr[0] = ['黑色'] i=0, j=0 func(skuarr, i+1, list) // 執行遞歸 skuarr[1] = ['s'] i=1, j=0 } else {
      // 拓展運算符合並數組 arr.push([...skuarr,list[i][j]]) // arr[0] = ['黑色','s','好'] i=2不符合if條件,執行else j=0 } }
return arr }
const list = [
  ['黑色','紅色','白色'],
  ['S','M'],
  ['好','差']
]
console.log(func([],0,list))
// 打印的結果
  1. 0:(3) ["黑色", "S", "好"]
  2. 1:(3) ["黑色", "S", "差"]
  3. 2:(3) ["黑色", "M", "好"]
  4. 3:(3) ["黑色", "M", "差"]
  5. 4:(3) ["紅色", "S", "好"]
  6. 5:(3) ["紅色", "S", "差"]
  7. 6:(3) ["紅色", "M", "好"]
  8. 7:(3) ["紅色", "M", "差"]
  9. 8:(3) ["白色", "S", "好"]
  10. 9:(3) ["白色", "S", "差"]
  11. 10:(3) ["白色", "M", "好"]
  12. 11:(3) ["白色", "M", "差"]
 

最近用數組的reduce方法時,想到了另外一種實現笛卡爾積的方法,補充進來函數

handleData () {
      // 測試的數據
      let arrs = [['紅','黃', '藍'], ['大', '中', '小']] // 若是你的數據類型是其餘形式,須要轉換成二維數組的格式再進行

      /**
       * 思路: 以第一項爲基礎,循環合併以後的每一項再循環的值
       * @param {*} acc 累計的值
       * @param {*} cur 當前遍歷項
       * @param {*} index 當前遍歷索引
       */ 
      let result = arrs.reduce((acc, cur, index) => {
        // 從第二項開始合併值
        if (index > 0) {
          let saveArr = []
          acc.forEach(item => {
            cur.forEach(subItem => {
              saveArr.push(`${item},${subItem}`)
            })
          })
          acc = saveArr
        }
        return acc
      }, arrs[0]) // 把數組的第一項傳入做爲初始值
      console.log(result) //["紅,大", "紅,中", "紅,小", "黃,大", "黃,中", "黃,小", "藍,大", "藍,中", "藍,小"]
    }

 

整個頁面的代碼,寫得比較亂,見諒測試

<template>
    <div>
        <div class="stand">
            <ul>
                <li class="attr" v-for="(item,index) in standData" :key="index">
                    <span @click="remove(index)">刪除:</span>
                    <el-input class="title" v-model="item.title" placeholder="請輸入屬性">:</el-input>
                    <div class="putt" v-if="item.attrs.length" v-for="(subitem,i) in item.attrs" :key="i">
                        <el-input v-model="subitem.attr" placeholder="請輸入值"></el-input>
                        <div class="close" @click="closeAtrr(index,i)">×</div>
                    </div>
                    <div class="append" @click="addAtrr(index)">+</div>
                </li>
            </ul>
            <div class="add">
                <el-button type="primary" @click="addStand">添加規格</el-button>
                <el-button type="primary" @click="getTable">生成規格列表</el-button>
                <el-button type="primary" @click="read">讀取規格列表</el-button>

            </div>
            
        </div>
        <div class="table">
            <el-table  v-if="isTable"
            :data="tableData"
            border
            style="width: 100%">
            <el-table-column
                prop="date"
                label="屬性"
                width="180">
            </el-table-column>
            <el-table-column
                prop="name"
                label="價格1"
                width="180">
            </el-table-column>
            <el-table-column
                prop="address"
                label="價格2">
            </el-table-column>
            </el-table>
        </div>
    </div>
</template>
<style>
    .table,.stand {
        padding: 40px;
    }
    .table {
        height: 500px;
    }
    .add {
        margin-top: 20px;
    }
    .attr {
        margin-bottom: 10px;
    }
    .el-input {
        width: auto;
        
    }
    .putt {
        display: inline-block;
        position: relative;
        margin-right: 10px;  
    }
    .append {
        width: 40px;
        height: 40px;
        background-color: aqua;
        line-height: 40px;
        text-align: center;
        display: inline-block;
        font-size: 28px;
        cursor: pointer;
        vertical-align: middle;
    }
    .title {
        background-color: bisque;
        margin-right: 10px;
    }
    .close {
        position: absolute;
        width: 15px;
        height: 15px;
        background-color: burlywood;
        border-radius: 50%;
        line-height: 15px;
        text-align: center;
        right: -5px;
        top: -5px;
    }
</style>

<script>
    export default {
      data() {
        return {
          tableData: [],
          input: '',
          isTable: false,
          standData: [],
          list: [],
          group: []
        }
      },
      created() {
          
      },
      methods: {
          // 添加規格行
          addStand (i) {
            //  限制規格種類不超過4種
              if (this.standData.length>3) {
                  this.$message('不能超過四行')
              } else {
                this.standData.push({title: '', attrs: []})
              }
          },
          // 添加規格表格
          getTable () {
              this.isTable = true
              this.tableData = []
              this.group = []
              this.list = []
            //   console.log(this.standData);
              const num = this.standData.length
              this.standData.forEach(item => {
                  this.list.push(item.attrs)
              });
            //   console.log(this.list);
             var arr = [] 
             var that = this 
             function func(skuarr=[], i){  
                for (let j=0; j<that.list[i].length; j++) {  
                    if (i<that.list.length-1) {  
                        skuarr[i] = that.list[i][j].attr  
                        func(skuarr, i+1)  
                    } else {  
                        arr.push([...skuarr,that.list[i][j].attr])  
                    }  
                }  
                return arr  
             }  
             let newList = func([], 0)
            let b
                 newList.forEach(item => {
                     b = ''
                     for (let i = 0; i < num; i++) {
                        let a = this.standData[i].title
                        a = a + ':' + item[i]
                        b = b + a + ';'
                     }
                     this.group.push(b)
                 })
             console.log(this.group)
             let table = []
             for (let j = 0; j < this.group.length; j++) {
                 table.push({
                     date: this.group[j],
                     name: '',
                     address: ''
                 })
             }
             this.tableData = table
          },
          
          // 刪除規格行
          remove (i) {
              this.standData.splice(i,1)
          },
          // 添加屬性值
          addAtrr (i) {
            //  限制屬性值不超過5個
            if (this.standData[i].attrs.length>4) {
                this.$message('不能超過5個')
             } else {
        // 存的時候是存的對象
this.standData[i].attrs.push({attr: ''}) } }, // 刪除屬性值 closeAtrr (a, b) { // console.log(a, b); this.standData[a].attrs.splice(b,1) }, // 讀取規格屬性數組 read () {
      // 若是後臺返回的數據是這樣的 const arr
= [ '顏色:紅色;尺碼:M;品質:好;', '顏色:紅色;尺碼:S;品質:好;', '顏色:白色;尺碼:M;品質:好;', '顏色:白色;尺碼:S;品質:好;' ] const a = arr[0].split(';') const num =a.length-1 let ss = [] for (let tt = 0; tt < num; tt++){ ss.push([]) } arr.forEach(item => { for (let tt = 0; tt < num; tt++){ ss[tt].push(item.split(';')[tt].split(':')[1]) } }) ss = ss.map(item => { return Array.from(new Set(item)) }) for (let s = 0; s < ss.length; s++) { for (let t = 0; t < ss[s].length; t++) { ss[s][t] = {attr:ss[s][t]} } } for (let i = 0; i < num; i++) { this.standData.push({'title': a[i].split(':')[0],attrs: ss[i]}) } console.log(this.standData); } } } </script>
相關文章
相關標籤/搜索