ThinkSSL🔒 一键申购 5分钟快速签发 30天无理由退款 购买更放心 广告
``` <!DOCTYPE html> <html lang="zh-CN" ng-strict-di> <meta charset="utf-8" /> <meta name="renderer" content="webkit" /> <meta http-equiv="Cache-Control" content="no-siteapp" /> <meta name="X-Context-Path" content="" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <head> <meta charset="utf-8" /> <title> 商品规格sku </title> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" /> <script src="js/vue.js" type="text/javascript" charset="utf-8"></script> <script src="https://unpkg.com/element-ui/lib/index.js"></script> <script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script> </head> <body> <style> .goods-spec { display: flex; justify-content: space-between; margin-bottom: 10px; } .goods-spec .goods-spec-add { margin-right: 15px; } .goods-container .button-new-tag { height: 32px; line-height: 30px; padding-top: 0; padding-bottom: 0; } .goods-container .input-new-tag { width: 90px; margin-right: 10px; vertical-align: bottom; } .goods-container .el-tag { margin-right: 10px; } .goods-container .goods-content { margin-bottom: 10px; padding: 14px; border: 1px solid #ebeef5; border-radius: 4px; background-color: #fcfcfc; } .goods-content .goods-content-box { display: flex; align-items: center; } .goods-content-box .goods-content-left { flex: 1; } </style> <div id="app"> <div style="padding:60px;"> <div class="goods-spec"> <span>商品规格</span> <el-link type="primary" @click="addPrivateSpec" class="goods-spec-add">添加规格</el-link> </div> <div class="goods-spec"> <el-checkbox-group v-model="checkList" > <div style="height: 30px;"> <el-checkbox v-for="(item,index) in attrN" @change="nv(item,index)" :key="index" :label="item"></el-checkbox> </div> <el-checkbox-group v-model="checkList1" v-for="(item,index) in attrV"> <div style="height: 30px;"> <el-checkbox v-show="attrft.includes(index)" @change="nvtwo(item,item1,index,index1)" v-for="(item1,index1) in item" :key="index1" :label="item1"></el-checkbox> </div> </el-checkbox-group> </el-checkbox-group> </div> <div class="goods-spec"> </div> <div class="goods-container" v-for="(attr, index) in privateGoodsItem" :key="index"> <div class="goods-content"> <div class="goods-content-box"> <div class="goods-content-left"> <el-form label-width="80px" style="width:400px"> <el-form-item label="规格名"> <el-input v-model="attr.goods_spec_spectitle" placeholder="请输入规格名"></el-input> </el-form-item> <el-form-item label="规格值"> <el-tag v-for="tag in attr.spec" :key="tag.goods_spec_info_title" closable :disable-transitions="false" @close="handleClose(tag, attr)"> {{ tag.goods_spec_info_title }} </el-tag> <el-input class="input-new-tag" v-if="attr.inputVisible" v-model="attr.inputValue" :ref="`saveTagInput${index}`" size="small" @keyup.enter.native="handleInputConfirm(attr.inputValue, attr)" @blur="handleInputConfirm(attr.inputValue, attr)" > </el-input> <el-button v-else class="button-new-tag" size="small" @click="showInput(attr, index)">+ 添加</el-button> </el-form-item> </el-form> </div> <div class="goods-content-right"> <el-link type="danger" @click="delPrivateSpec(index)">删除规格</el-link> </div> </div> </div> </div> <p style="margin:24px 0 10px 0">价格 / 库存</p> <el-table ref="multipleTable" :data="tableColumnList.tableBodyList" stripe tooltip-effect="dark" style="width: 100%;margin-top:1%;"> <el-table-column :label="item.propName" :property="item.prop" v-for="item in tableColumnList.tableHeaderList" :key="item.prop" align="center"> <template slot-scope="scope"> <span>{{ scope.row[scope.column.property].goods_spec_info_title }}</span> </template> </el-table-column> <el-table-column label="价格(元)"> <template slot-scope="scope"> <el-input v-model.number="scope.row.price"></el-input> </template> </el-table-column> <el-table-column label="库存"> <template slot-scope="scope"> <el-input v-model.number="scope.row.stock"></el-input> </template> </el-table-column> <el-table-column label="库存预警"> <template slot-scope="scope"> <el-input v-model.number="scope.row.low_stock"></el-input> </template> </el-table-column> </el-table> </div> </div> <script> let yuan = [] // let yuan = [{ // goods_spec_id: 1, // goods_spec_gid: 1, // goods_spec_spectitle: "颜色", // goods_spec_sort: 1, // goods_spec_status: 1, // spec: [ // { // goods_spec_info_id: 1, // goods_spec_info_gid: 1, // goods_spec_info_specid: 1, // goods_spec_info_title: "白色", // goods_spec_info_src: "", // goods_spec_info_sort: 0, // goods_spec_info_status: 1 // }, // { // goods_spec_info_id: 2, // goods_spec_info_gid: 1, // goods_spec_info_specid: 1, // goods_spec_info_title: "黑色", // goods_spec_info_src: "", // goods_spec_info_sort: 0, // goods_spec_info_status: 1 // } // ] // }] var app = new Vue({ el: '#app', data: { newVal1:{}, kv:true, a:0, listtwo: [], listtwob: [], listspec: [ { goods_spec_id: 1, goods_spec_gid: 1, goods_spec_spectitle: "颜色", goods_spec_sort: 1, goods_spec_status: 1, spec: [ { goods_spec_info_id: 1, goods_spec_info_gid: 1, goods_spec_info_specid: 1, goods_spec_info_title: "白色", goods_spec_info_src: "", goods_spec_info_sort: 0, goods_spec_info_status: 1 }, { goods_spec_info_id: 2, goods_spec_info_gid: 1, goods_spec_info_specid: 1, goods_spec_info_title: "黑色", goods_spec_info_src: "", goods_spec_info_sort: 0, goods_spec_info_status: 1 } ] }, { goods_spec_id: 2, goods_spec_gid: 1, goods_spec_spectitle: "重量", goods_spec_sort: 2, goods_spec_status: 1, spec: [ { goods_spec_info_id: 3, goods_spec_info_gid: 1, goods_spec_info_specid: 2, goods_spec_info_title: "1kg", goods_spec_info_src: "", goods_spec_info_sort: 0, goods_spec_info_status: 1 }, { goods_spec_info_id: 4, goods_spec_info_gid: 1, goods_spec_info_specid: 2, goods_spec_info_title: "2kg", goods_spec_info_src: "", goods_spec_info_sort: 0, goods_spec_info_status: 1 }, { goods_spec_info_id: 17, goods_spec_info_gid: 0, goods_spec_info_specid: 2, goods_spec_info_title: "3kg", goods_spec_info_src: "", goods_spec_info_sort: 0, goods_spec_info_status: 1 }, { goods_spec_info_id: 22, goods_spec_info_gid: 0, goods_spec_info_specid: 2, goods_spec_info_title: "4kg", goods_spec_info_src: "", goods_spec_info_sort: 0, goods_spec_info_status: 1 } ] }, { goods_spec_id: 7, goods_spec_gid: 0, goods_spec_spectitle: "材质", goods_spec_sort: 3, goods_spec_status: 1, spec: [ { goods_spec_info_id: 23, goods_spec_info_gid: 0, goods_spec_info_specid: 7, goods_spec_info_title: "玻璃", goods_spec_info_src: "", goods_spec_info_sort: 0, goods_spec_info_status: 1 }, { goods_spec_info_id: 24, goods_spec_info_gid: 0, goods_spec_info_specid: 7, goods_spec_info_title: "塑料", goods_spec_info_src: "", goods_spec_info_sort: 0, goods_spec_info_status: 1 }, { goods_spec_info_id: 25, goods_spec_info_gid: 0, goods_spec_info_specid: 7, goods_spec_info_title: "金属", goods_spec_info_src: "", goods_spec_info_sort: 0, goods_spec_info_status: 1 } ] } ], checkList:[], checkList1:[], attrN: ["颜色", "重量", "材质"], attrV: [ [ "白色", "黑色" ], [ "1kg", "2kg", "3kg", "4kg" ], [ "玻璃", "塑料", "金属" ] ], attrft:[], showarr:{}, tableColumnList: { tableHeaderList: [], tableBodyList: [] // inventory: '' }, privateGoodsItem: [ { goods_spec_spectitle: '', //规格名 spec: [{ goods_spec_info_title:'' } ], //规格值数组 inputVisible: false, inputValue: '' } ] }, computed: { // 计算规格 calculateAttribute() { console.log('145'); // 初始化 let obj = {} this.privateGoodsItem.forEach((item) => { // 判断有没有输入规格名 if (item.goods_spec_spectitle) { //规格名:规格值 //'颜色':'尺寸' //console.log(item.spec); obj[item.goods_spec_spectitle] = item.spec } }) //console.log(obj); return obj } }, watch: { //计算规格值差 checkList1(newVal,oldVal){ console.log('352',this.showarr); v = this.showarr.goods_spec_spectitle if(oldVal.length>newVal.length){ let diff = oldVal.filter((val)=> { return newVal.indexOf(val) === -1 }) d = this.newVal1[v] d.forEach((n,index)=>{ if(n.goods_spec_info_title == diff[0]){ this.newVal1[v].splice(index, 1) } }) //this.listspec this.privateGoodsItem this.listspec.forEach((n,index)=>{ //console.log('363',n); if(n.goods_spec_spectitle == v){ console.log('365',index); this.listspec[index].spec.forEach((m,index)=>{ if(m.goods_spec_info_title == diff[0]){ m.a = false } }) //w. //w.spec.splice(index, 1) //a = index; } }) this.privateGoodsItem.forEach((n,index)=>{ //console.log('363',n); if(n.goods_spec_spectitle == v){ console.log('365',index); this.privateGoodsItem[index].spec.forEach((m,i)=>{ if(m.goods_spec_info_title == diff[0]){ this.privateGoodsItem[index].spec.splice(i,1) } }) //w. //w.spec.splice(index, 1) //a = index; } }) } console.log('372',this.listspec); console.log('368',this.newVal1); }, //计算规格名差集 checkList(newVal,oldVal){ console.log('351'); //console.log('347',oldVal); //console.log('348',newVal); //const a = null; if(oldVal.length>newVal.length){ let diff = oldVal.filter((val)=> { return newVal.indexOf(val) === -1 }) //console.log(diff); diff.forEach(item=>{ this.privateGoodsItem.forEach((n,index)=>{ if(n.goods_spec_spectitle == item){ //console.log(index); this.privateGoodsItem.splice(index, 1) //a = index; } }) }) } if(oldVal.length<newVal.length){ let diff = newVal.filter((val)=> { return oldVal.indexOf(val) === -1 }) //console.log(diff); diff.forEach(item=>{ this.privateGoodsItem.forEach((n,index)=>{ if(n.goods_spec_spectitle == item){ // console.log(index); //this.privateGoodsItem.splice(index, 1) this.a = index; } }) }) } //console.log('377',this.a); }, // 监听规格数据 calculateAttribute :{ handler(newVal) { console.log('161'); // console.log('369',newVal); // let cloneNewVal = newVal; // if(this.kv){ // console.log('388',this.privateGoodsItem); // b = this.privateGoodsItem[this.a].spec // console.log(b); // } // let cloneNewVal = [] // Object.assign(cloneNewVal,newVal) cloneNewVal = JSON.parse(JSON.stringify(newVal)) Object.assign([],this.newVal1,cloneNewVal) //console.log('398',this.newVal1); //console.log('386',cloneNewVal); let attrName = [] //规格名数组 let attrValue = [] //规格值数组 // for (let key in cloneNewVal) { // console.log('393'); // attrName.push(key) // attrValue.push(cloneNewVal[key]) // console.log('402',attrValue); // if(this.checkList.includes(key) && this.checkList1.length > 0){ // console.log(attrName); // menuList = this.filterMenu(this.listspec); // Object.assign(this.privateGoodsItem,menuList) // b = this.privateGoodsItem[this.a] // attrValue.push(b.spec) // console.log('401',attrValue); // console.log(this.listspec); // } // } for (let key in cloneNewVal) { attrName.push(key) attrValue.push(cloneNewVal[key]) } // 表格内容数据(笛卡尔积算法) let finalArr = this.cartesianProductOf(...attrValue) let tableObj = { tableBodyList: [], tableHeaderList: [] } // 表格内容 tableObj.tableBodyList = finalArr.map((item) => { let obj = { price: 0, stock: 0, low_stock: 0 } for (let i = 0; i < item.length; i++) { obj[attrName[i]] = item[i] } return obj }) this.tableColumnList.tableBodyList = tableObj.tableBodyList //表格内容数据 // 表头 let skuTableArr = Object.keys(newVal) tableObj.tableHeaderList = skuTableArr.map((item) => { return { prop: item, propName: item } }) this.tableColumnList.tableHeaderList = tableObj.tableHeaderList // 表头 }, deep:true }, }, mounted() { yuan.forEach((item)=>{ item.inputVisible=false, item.inputValue='' }) this.listspec.forEach((item)=>{ item.inputVisible=true, item.inputValue='', item.a = false item['spec'].forEach(n=>{ n.a = false }) }) // console.log(this.listspec); //this.privateGoodsItem=yuan }, methods: { //获取规格 nvtwo(item,item1,index,index1){ // console.log('470',item); //console.log('471',item1); //console.log('472',index); // console.log('473',index1); a = this.attrN[index] b = this.newVal1[a] //this.newVal1[a]=item1 if(b){ // console.log('481',b); b.push({'goods_spec_info_title':item1}) this.newVal1[a] = b }else{ // console.log('483',b); c = [] c.push({'goods_spec_info_title':item1}) this.newVal1[a] = c //console.log('487',this.newVal1); } console.log('479',this.newVal1); this.listspec.forEach(item=>{ if(item.a == true){ item.spec.forEach(item1=>{ if( this.checkList1.includes(item1.goods_spec_info_title)){ item1.a = true } }) } }) console.log('545',this.listspec); menuList = this.filterMenu(this.listspec); console.log('547',menuList); b = {} menuList.forEach((item)=>{ if(item.goods_spec_spectitle == this.attrN[index]){ b = item.spec } }) // console.log('620',b); // console.log(619,this.attrN[index]) // obj = {} //console.log(item1); // obj[this.attrN[index]]=b // obj[this.attrN[index]].push(b) // console.log('622',obj); // this.newVal1 = obj Object.assign(this.privateGoodsItem,menuList) b = this.privateGoodsItem[this.a] b['inputVisible'] = true console.log('639',b.spec); console.log('641',this.a) this.showInput(b,this.a) //calculateAttribute() //value // item['spec'].filter(item1=>this.checkList1.includes(item1.goods_spec_info_title) == true) // c = b['spec'].filter(item=>this.checkList1.includes(item.goods_spec_info_title) == true) // a.filter(item=>{ // a.pop(item) // // console.log(item.goods_spec_spectitle); // // if(!this.checkList.includes(item.goods_spec_spectitle)){ // // a.pop(item) // // } // }) // console.log(c); // console.log(this.listtwo); // console.log(c); }, nvtwo1(index,index1){ p = this.privateGoodsItem console.log('nvtwo') console.log(index) console.log(index1) a = this.listspec[index] b = a.spec[index1] console.log(a); console.log(b) let c = JSON.parse(JSON.stringify(a)) c['spec']=[] c['spec'].push(b); console.log(c); c['inputVisible']=false c['inputValue']='' d = p.concat(c) this.privateGoodsItem = d console.log(this.privateGoodsItem); // c.forEach((item)=>{ // item.inputVisible=false, // item.inputValue='' // }) // this.privateGoodsItem=c }, nv(item,index){ // console.log(this.privateGoodsItem.length); // if(this.privateGoodsItem>0){ // this.privateGoodsItem.forEach(n=>{ // if(!n.goods_spec_spectitle == item){ // n.goods_spec_spectitle // } // }) // }else{ // this.privateGoodsItem.unshift({ // goods_spec_spectitle: item, // spec: [], // inputVisible: false, // inputValue: '' // }) // } this.listspec.forEach(item=>{ if(this.checkList.includes(item.goods_spec_spectitle) == true){ item.a = true item.inputVisible = true } }) if(this.checkList.length){ const a =[] this.checkList.forEach(i=>{ t = this.attrN.indexOf(i) // console.log(t); a.push(t) this.attrft = a // console.log(this.attrft); if(i == item){ this.privateGoodsItem.unshift({ goods_spec_spectitle: item, spec: [], inputVisible: false, inputValue: '' }) } }) } // if() }, nv1(item,index){ if(this.privateGoodsItem>0){ }else{ this.privateGoodsItem.push({ goods_spec_spectitle: item, spec: [ ], inputVisible: false, inputValue: '' }) } console.log('nv'); //this.checkList if(this.checkList.length){ const a =[] this.checkList.forEach(item=>{ t = this.attrN.indexOf(item) // console.log(t); a.push(t) this.attrft = a // console.log(this.attrft); }) } b = this.listspec.filter(item=>this.checkList.includes(item.goods_spec_spectitle) == true) console.log(b); this.listtwob = b console.log(this.listtwob); this.listtwo = b this.listspec.forEach(item=>{ if(this.checkList.includes(item.goods_spec_spectitle) == true){ item.a = true } }) console.log(this.listspec); }, //递归函数 filterMenu(menuList) { return menuList.filter(item => { return item.a == true; }).map(item => { item = Object.assign({}, item) if(item.spec && item.spec.length > 0) { item.spec = this.filterMenu(item.spec) } return item }) }, // filterMenu(){ // menuList => { // return menuList.filter(item => { // return item.a == true; // }).map(item => { // item = Object.assign({}, item) // if(item.spec && item.spec.length > 0) { // item.spec = this.filterMenu(item.spec) // } // return item // }) // } // }, // 添加规格 addPrivateSpec(index) { console.log('205'); this.privateGoodsItem.push({ goods_spec_spectitle: '', spec: [], inputVisible: false, inputValue: '' }) console.log('658',this.privateGoodsItem); }, delPrivateSpec(index) { this.privateGoodsItem.splice(index, 1) }, handleInputConfirm(val, attr) { if (val) { attr.spec.push({goods_spec_info_title:val}) } attr.inputVisible = false attr.inputValue = '' }, handleClose(tag, item) { item.spec.splice(item.spec.indexOf(tag), 1) }, showInput(attr, index) { this.showarr = attr console.log(attr); console.log(index); attr.inputVisible = true this.$nextTick((_) => { this.$refs[`saveTagInput${index}`][0].$refs.input.focus() }) }, // 笛卡尔积算法 cartesianProductOf(...args) { return args.reduce( (total, current) => { let ret = [] total.forEach((a) => { current.forEach((b) => { ret.push(a.concat([b])) }) }) return ret }, [[]] ) } } }) </script> </body> </html> ```