vue+element实现商品多规格的添加(sku)

时间:2025-02-15 14:45:59
<!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> <title> 商品规格sku </title> <link rel="stylesheet" href="/element-ui/lib/theme-chalk/" /> </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-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="" placeholder="请输入规格名"></el-input> </el-form-item> <el-form-item label="规格值"> <el-tag v-for="tag in " :key="tag" closable :disable-transitions="false" @close="handleClose(tag, attr)"> {{ tag }} </el-tag> <el-input class="input-new-tag" v-if="" v-model="" :ref="`saveTagInput${index}`" size="small" @="handleInputConfirm(, attr)" @blur="handleInputConfirm(, 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="" stripe tooltip-effect="dark" style="width: 100%;margin-top:1%;"> <el-table-column :label="" :property="" v-for="item in " :key="" align="center" fixed="left"> <template slot-scope="scope"> <span>{{ [] }}</span> </template> </el-table-column> <el-table-column label="价格(元)" :render-header="renderHeader" align="center" width="160"> <template slot-scope="scope"> <el-input size="mini" clearable placeholder="保留两位小数点" @change="goodsPrice" v-model=""></el-input> </template> </el-table-column> <el-table-column label="市场价(元)" :render-header="renderHeader" align="center" width="150"> <template slot-scope="scope"> <el-input size="mini" clearable placeholder="保留两位小数点" @change="goodsMarketPrice" v-model=""></el-input> </template> </el-table-column> <el-table-column label="商品重量(kg)" :render-header="renderHeader" align="center" width="150"> <template slot-scope="scope"> <el-input size="mini" clearable placeholder="保留两位小数点" @change="goodsCubage" v-model=""></el-input> </template> </el-table-column> <el-table-column label="库存" :render-header="renderHeader" align="center" width="150"> <template slot-scope="scope"> <el-input size="mini" type="number" placeholder="请输入整数" @change="goodsStock" v-model=""></el-input> </template> </el-table-column> <el-table-column label="库存预警值" align="center" width="150"> <template slot-scope="scope"> <el-input size="mini" type="number" placeholder="请输入整数" @change="goodsAlarm" v-model=""></el-input> </template> </el-table-column> <el-table-column label="限购数量" align="center" width="150"> <template slot-scope="scope"> <el-input size="mini" type="number" placeholder="请输入整数" @change="goodsMaxSale" v-model=""></el-input> </template> </el-table-column> </el-table> </div> </div> <!-- 先引入 Vue --> <script src="/vue/dist/"></script> <!-- 引入组件库 --> <script src="/element-ui/lib/"></script> <script src="/vue-resource/1.5.1/"></script> <script> var app = new Vue({ el: '#app', data: { tableColumnList: { tableHeaderList: [], tableBodyList: [] // inventory: '' }, privateGoodsItem: [ { privateSpecName: '', //规格名 dynamicTags: [], //规格值数组 inputVisible: false, inputValue: '' } ] }, computed: { // 计算规格 calculateAttribute() { // 初始化 let obj = {} this.privateGoodsItem.forEach((item) => { // 判断有没有输入规格名 if (item.privateSpecName) { //规格名:规格值 //'颜色':'尺寸' obj[item.privateSpecName] = item.dynamicTags } }) return obj } }, watch: { // 监听规格数据 calculateAttribute(newVal) { let cloneNewVal = JSON.parse(JSON.stringify(newVal)) let attrName = [] //规格名数组 let attrValue = [] //规格值数组 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 // 表头 } }, methods: { // 添加规格 addPrivateSpec(index) { this.privateGoodsItem.push({ privateSpecName: '', dynamicTags: [], inputVisible: false, inputValue: '' }) }, delPrivateSpec(index) { this.privateGoodsItem.splice(index, 1) }, handleInputConfirm(val, attr) { if (val) { attr.dynamicTags.push(val) } attr.inputVisible = false attr.inputValue = '' }, // 动态表格的某列的必填参数 renderHeader(cerateElement, { column }) { return cerateElement('div', [ cerateElement('span', column.label), cerateElement('span', { domProps: { innerHTML: '*' }, style: { color: 'red', fontSize: '16px', marginLeft: '5px' } }) ]); }, handleClose(tag, item) { item.dynamicTags.splice(item.dynamicTags.indexOf(tag), 1) }, showInput(attr, 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>