element根據(jù)輸入動(dòng)態(tài)生成表格的示例代碼
場(chǎng)景:后臺(tái)頁(yè)面根據(jù)商品規(guī)格和規(guī)格值,動(dòng)態(tài)(增刪改查)在表格中生成對(duì)應(yīng)的sku. 如圖:
代碼如下:
edit.html
<template xmlns=""> <div class="app-container"> <el-form ref="form" :model="form" label-width="80px" autocomplete="off" @submit.native.prevent> <h3>基礎(chǔ)信息</h3> <div style="padding-left: 60px"> <el-row> <el-col :span="7"> <el-form-item label="spu_id"> <el-input v-model="form.id" autocomplete="off" placeholder="" :disabled="true" /> </el-form-item> </el-col> <el-col :span="5"> <el-form-item label="名稱" :required="true"> <el-input v-model="form.goods_name" autocomplete="off" placeholder="" /> </el-form-item> </el-col> <el-col :span="5"> <el-form-item label="商品類型" :required="true"> <el-select v-model="form.goods_type" placeholder="請(qǐng)選擇"> <el-option v-for="item in goodsTypeOptions" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="5"> <el-form-item label="品牌" :required="true"> <el-select v-model="form.brand_code" style="width: 100%"> <el-option v-for="item in brandOptions" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-form-item> </el-col> <el-col :span="5"> <el-form-item label="分類" :required="true"> <el-cascader v-model="form.cate_code" collapse-tags clearable :options="cateOptions" :props="{ multiple: false, checkStrictly: true }" filterable style="width: 100%" /> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="5"> <el-form-item label="贈(zèng)品" :required="true"> <el-radio v-model="form.is_gift" label="1">否</el-radio> <el-radio v-model="form.is_gift" label="2">是</el-radio> </el-form-item> </el-col> <el-col :span="5"> <el-form-item label="列表顯示" :required="true"> <el-radio v-model="form.is_show_video" label="1">是</el-radio> <el-radio v-model="form.is_show_video" label="2">否</el-radio> </el-form-item> </el-col> <el-col :span="5"> <el-form-item label="是否套組" :required="true"> <el-radio v-model="form.is_suite" label="1">否</el-radio> <el-radio v-model="form.is_suite" label="2">是</el-radio> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="5"> <el-form-item label="是否預(yù)售" :required="true"> <el-radio v-model="form.is_pre_sales" label="1">否</el-radio> <el-radio v-model="form.is_pre_sales" label="2">是</el-radio> </el-form-item> </el-col> <el-col :span="5"> <el-form-item label="是否臨期" :required="true"> <el-radio v-model="form.is_expire" label="1">否</el-radio> <el-radio v-model="form.is_expire" label="2">是</el-radio> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="5"> <el-form-item label="包裝規(guī)格"> <el-input v-model="form.pack_spec" autocomplete="off" placeholder="" /> </el-form-item> </el-col> <el-col :span="5"> <el-form-item label="包裝數(shù)量"> <el-input v-model="form.pack_count" autocomplete="off" placeholder="" /> </el-form-item> </el-col> <el-col :span="5"> <el-form-item label="銷售單位"> <el-input v-model="form.unit_name" autocomplete="off" placeholder="" /> </el-form-item> </el-col> <el-col :span="5"> <el-form-item label="保質(zhì)期"> <el-date-picker v-model="form.expire_date" type="date" value-format="yyyy-MM-dd" placeholder="選擇日期" /> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="24"> <el-form-item label="商品圖片" :required="true"> <ul class="el-upload-list el-upload-list--picture-card"> <vuedraggable v-model="form.images"> <li v-for="(item, index) in form.images" :key="index" class="el-upload-list__item is-success animated"> <img :src="item" alt="" class="el-upload-list__item-thumbnail "> <i class="el-icon-close" /> <span class="el-upload-list__item-actions"> <!-- 預(yù)覽 --> <span class="el-upload-list__item-preview" @click="viewImage(item)"> <i class="el-icon-zoom-in" /> </span> <!-- 刪除 --> <span class="el-upload-list__item-delete" @click="delImage(index)"> <i class="el-icon-delete" /> </span> </span> </li> </vuedraggable> </ul> <!-- <el-button size="small" type="info" @click="uploadImageDialog = true">點(diǎn)擊上傳</el-button>--> <label for="upload-btn" class="el-button el-button--info el-button--mini">上傳文件</label> <input v-show="false" id="upload-btn" ref="uploadBtn" type="file" accept="image/png, image/jpeg, image/gif, image/jpg" @change="loadImg($event)" > <div class="el-upload__tip">第1張為主圖,其它為從圖.尺寸800*800</div> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="7"> <el-form-item label="推薦語(yǔ)"> <el-input v-model="form.recommendation" autocomplete="off" placeholder="" /> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="24"> <el-form-item label="描述" :required="true"> <tinymce v-model="form.description" :height="300" /> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="保管事項(xiàng)"> <el-select v-model="form.keep_desc_tpl_id" placeholder="請(qǐng)選擇" style="width: 100%"> <el-option v-for="item in keepOptions" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="溫馨提示"> <el-select v-model="form.notice_desc_tpl_id" placeholder="請(qǐng)選擇" style="width: 100%"> <el-option v-for="item in noticeOptions" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-form-item> </el-col> </el-row> </div> <h3>sku信息</h3> <div style="padding-left: 60px"> <sku-edit ref="skuEdit" /> </div> <el-form-item> <el-button type="primary" @click="save">保存</el-button> <router-link style="padding-left: 10px;" to="/goods/erp-goods-list"> <el-button>返回列表</el-button> </router-link> </el-form-item> </el-form> <el-dialog :visible.sync="imageViewDialog"> <img width="100%" :src="imageViewUrl" alt=""> </el-dialog> <el-dialog width="700px" custom-class="image-upload" :visible.sync="croperImageDialog" :close-on-click-modal="false" @close="emptyUpload" > <div style="display:flex;justify-content: center;"> <cropper ref="myCropper" @updateImageList="updateImageList" /> </div> <div slot="footer"> <div class="dialog-footer-btn"> <div> <el-button @click="croperImageDialog = false">返 回</el-button> <el-button type="primary" @click="cropImg">確 定</el-button> </div> </div> </div> </el-dialog> </div> </template> <script> import { spuCreate, spuDetail } from '@/api/goods/goods' import { getOptions, uploadUrl } from '@/api/common/common' import { empty } from '@/utils/index' import Tinymce from '@/components/Tinymce/index.vue' import skuEdit from '@/views/goods/goods/sku_edit.vue' import { getToken } from '@/utils/auth' import vuedraggable from 'vuedraggable' import cropper from '@/views/goods/component/cropper.vue' export default { name: 'GoodsEdit', components: { Tinymce, vuedraggable, cropper, skuEdit }, props: ['id'], data() { return { salesAmountLimit: 1, uploadImageDialog: false, croperImageDialog: false, imageViewDialog: false, imageViewUrl: false, uploadUrl: uploadUrl, cropperDialogVisible: false, tagOptions: [], keepOptions: [], noticeOptions: [], uppy: {}, cateOptions: [], brandOptions: [], goodsTypeOptions: [], uploadHeaders: { token: getToken() }, leftTagFileList: [], rightTagFileList: [], form: {}, copy: false, initForm: { id: '', goods_name: '', barcode: '', cate_code: '', brand_code: '', description: '', images: [], pack_spec: '', pack_count: '', unit_name: '', expire_date: '', video: '', is_expire: '1', is_gift: '1', is_pre_sales: '1', video_cover: '', is_show_video: '1', recommendation: '', goods_type: '1', is_suite: '1', merchant_id: '', keep_desc_tpl_id: '', notice_desc_tpl_id: '', sku_map_list: [], spu_attrs: [] } } }, computed: {}, watch: { 'form.left_tag_type': { deep: true, handler(newVal, oldVal) { if ((newVal === 7 && oldVal !== 7) || (newVal !== 7 && oldVal === 7)) { this.form.left_tag = '' this.leftTagFileList = [] } } }, 'form.right_tag_type': { deep: true, handler(newVal, oldVal) { if ((newVal === 7 && oldVal !== 7) || (newVal !== 7 && oldVal === 7)) { this.form.right_tag = '' this.rightTagFileList = [] } } } }, mounted() { if (this.$route.query.copy) { this.copy = JSON.parse(this.$route.query.copy) } }, activated() { this.form = JSON.parse(JSON.stringify(this.initForm)) this.detail() getOptions({ option_names: [ 'cateOptions', 'brandOptions', 'goodsTypeOptions', 'goodsDescTplOption', 'goodsKeepTplOption'] }).then(response => { this.goodsTypeOptions = response.data.goodsTypeOptions this.cateOptions = response.data.cateOptions this.brandOptions = response.data.brandOptions this.keepOptions = response.data.goodsKeepTplOption this.noticeOptions = response.data.goodsDescTplOption }) }, methods: { async save() { // 獲取 skuEdit 子組件 的信息 this.form.sku_map_list = this.$refs.skuEdit.spuInfo.sku_map_list // is_draft =1 為草稿數(shù)據(jù) 2-為審核通過(guò)的數(shù)據(jù) this.form.is_draft = 2 await spuCreate(this.form) this.$message({ message: '保存成功,待審核!', type: 'success' }) this.form = JSON.parse(JSON.stringify(this.initForm)) this.$router.push({ path: '/goods/goods/draft-list' }) }, detail() { const id = this.$route.query.id const params = {} params.id = id if (empty(id)) { return } spuDetail(params).then(response => { this.form = response.data this.$refs.skuEdit.spuInfo.sku_map_list = this.form.sku_map_list this.$refs.skuEdit.spuAttrs = this.form.spu_attrs this.form.is_expire = this.form.is_expire.toString() this.form.is_gift = this.form.is_gift.toString() this.form.is_show_video = this.form.is_show_video.toString() this.form.is_suite = this.form.is_suite.toString() this.form.is_pre_sales = this.form.is_pre_sales.toString() this.form.is_expire = this.form.is_expire.toString() if (this.copy) { this.form.id = '' } }) }, viewImage(item) { this.imageViewUrl = item.url this.imageViewDialog = true }, delImage(index) { this.form.images.splice(index, 1) }, loadImg(e) { const file = e.target.files[0] if (file.size / 1024 / 1024 > 5) { this.$message.error('上傳文件不能超過(guò)5M') return false } if (!/\.(jpg|png|gif|JPG|PNG|GIF|)$/.test(file.name)) { this.$message.info('圖片類型必須是jpg,png的一種') return false } const reader = new FileReader() reader.onload = (e) => { let data if (typeof e.target.result === 'object') { data = window.URL.createObjectURL(new Blob([e.target.result])) } else { data = e.target.result } this.croperImageDialog = true this.$nextTick(() => { this.$refs.myCropper.imgLoad(file, data) }) } reader.readAsArrayBuffer(file) }, emptyUpload() { this.$refs.uploadBtn.value = '' }, cropImg() { this.$refs.myCropper.crop() }, updateImageList(item) { this.form.images.push(item.url) this.croperImageDialog = false } } } </script> <style lang="scss" scoped> .app-container { overflow-y: auto; height: 100%; } .app-container >>> .cropper-modal { opacity: 0.5; } el-input { width: 300px; } </style>
子組件sku_edit.html
<template> <div class=""> <el-form ref="SkuEdit" label-width="110px"> <el-form-item label="spu規(guī)格" required> <vuedraggable v-model="spuAttrs" @start="onStart" @end="onEnd"> <transition-group> <template v-for="(item, index) in spuAttrs"> <div :key="index" :class="(index < (spuAttrs.length - 1)) ? 'attr_select_index' : '' "> <div> <el-select v-model="item.attr" filterable allow-create placeholder="選擇或創(chuàng)建" size="mini" @blur="addAttr($event,item,index)" @change="changeAttr($event, index)" > <el-option v-for="(cateItem, cateIndex) in cateAttrs" :key="cateIndex" :label="cateItem.label" :value="cateIndex" /> </el-select> <i :key="index" class="item el-icon-sort" @mouseover="showTooltipSpec" @mouseleave="hideTooltipSpec" /> <span v-if="tooltipVisibleSpec&&index===0">拖動(dòng)上下排序</span> <i :key="index" class="el-icon-circle-plus attr_options_add" @click="spuAttrItem(1, index + 1)" /> <i v-if="spuAttrs.length>1" :key="index" class="el-icon-remove attr_options_del" @click="spuAttrItem(2,index)" /> </div> <div style="margin-left: 20px"> <vuedraggable v-model="item.values" @start="onStart" @end="onEnd"> <transition-group style="display: flex; flex-wrap: wrap;"> <template v-for="(attrVal,vi) in item.values"> <div :key="vi"> <div style="margin-left: 15px"> <el-input v-model="item.values[vi]" placeholder="添加規(guī)格值" size="mini" style="width: 100px;" @blur="addAttrValue($event,index, vi)" /> <template> <i :key="vi" class="item el-icon-s-operation" @mouseover="showTooltipSpecValue" @mouseleave="hideTooltipSpecValue" /> <span v-if="tooltipVisibleSpecValue&&vi===0&&index===0">拖動(dòng)左右排序</span> <i :key="vi" class="el-icon-circle-plus attr_val_options_add" @click="spuAttrValueItem(1,index)" /> <i v-if="item.values.length>1" :key="vi" class="el-icon-remove attr_val_options_del" @click="spuAttrValueItem(2,index,vi)" /> </template> </div> </div> </template> </transition-group> </vuedraggable> </div> </div> </template> </transition-group> </vuedraggable> </el-form-item> <el-form-item label="映射sku" required> <el-table :data="spuInfo.sku_map_list" border :header-row-style="tableHeaderRowStyle" :header-cell-style="tableHeaderCellStyle" :max-height="tableHeight" size="mini" style="width: 100%" empty-text="暫無(wú)數(shù)據(jù)" > <el-table-column v-for="(item,index) in spuAttrs" :key="index" :label="item.attr" > <template slot-scope="scop"> <div>{{ getAttrValue(scop.row, index) }}</div> </template> </el-table-column> <el-table-column prop="barcode" label="商品條碼" > <template slot-scope="scope"> <el-input v-model="scope.row.barcode" size="mini" placeholder="請(qǐng)輸入商品條碼" @blur="addBarcode($event,scope.row,scope.$index)" /> </template> </el-table-column> <el-table-column prop="price" label="售價(jià)" > <template slot-scope="scope"> <el-input v-model="scope.row.price" size="mini" placeholder="請(qǐng)輸入商品售價(jià)" @blur="addPrice($event,scope.row,scope.$index)" /> </template> </el-table-column> <el-table-column prop="market_price" label="市場(chǎng)價(jià)" > <template slot-scope="scope"> <el-input v-model="scope.row.price" size="mini" placeholder="請(qǐng)輸入商品市場(chǎng)價(jià)" @blur="addMarketPrice($event,scope.row,scope.$index)" /> </template> </el-table-column> <el-table-column prop="image" label="圖片" width="100" > <template slot-scope="scope"> <el-upload class="avatar-uploader" :action="uploadUrl+'?type=image'" :limit="1" :show-file-list="false" :on-success="(res,file,fileList) => {handleAvatarSuccess(res,file,fileList,scope.$index)}" :headers="uploadHeaders" > <img v-if="scope.row.image!=''" :src="scope.row.image" class="avatar"> <i v-else class="el-icon-plus avatar-uploader-icon" /> </el-upload> </template> </el-table-column> </el-table> </el-form-item> </el-form> </div> </template> <script> import vuedraggable from 'vuedraggable' import { getOptions, uploadUrl } from '@/api/common/common' import { spuDetail, saveSpu } from '@/api/goods/spu' import { empty } from '@/utils' import Common from '@/layout/mixin/Common' import { getToken } from '@/utils/auth' export default { name: 'SkuEdit', components: { 'vuedraggable': vuedraggable }, mixins: [Common], props: ['spu_id'], data() { return { // 1-為規(guī)格 2-為規(guī)格值 changeType: 1, // 變化內(nèi)容 changeContent: '', drag: false, tooltipVisibleSpec: false, tooltipVisibleSpecValue: false, uploadUrl: uploadUrl, spuInfo: { sku_map_list: [] }, uploadHeaders: { token: getToken() }, cateAttrs: [], cateAttrCount: 0, spuAttrs: [], selectMapSkuVisible: false, skuListLoading: false, skuList: [], barcode: '', goodsName: '', selectSkuPage: 1, selectSkuPageSize: 30, selectSkuTotal: 0, selectSkuMapIndex: -1 } }, mounted() { getOptions({ option_names: ['spuSpecOptions'] }).then(response => { this.cateAttrs = response.data.spuSpecOptions }) if (!empty(this.spu_id)) { this.spuInfo.id = this.spu_id spuDetail({ id: this.spu_id }).then(res => { this.cateAttrCount = Object.keys(this.cateAttrs).length this.spuInfo.sku_map_list = res.data.sku_map_list this.spuAttrs = res.data.spu_attrs this.$refs.imageCropperUpload.setImage([{ path: this.spuInfo.image, url: this.spuInfo.image_url }]) }) } if (empty(this.spuAttrs)) { this.spuAttrs = [ { attr: '', values: [''] } ] } }, methods: { empty, showTooltipSpec() { console.log('showTooltipSpec','----------') setTimeout(() => { this.tooltipVisibleSpec = true }, 1000) }, hideTooltipSpec() { console.log('hideTooltipSpec','----------') this.tooltipVisibleSpec = false }, showTooltipSpecValue() { console.log('showTooltipSpecValue','----------') setTimeout(() => { this.tooltipVisibleSpecValue = true }, 1000) }, hideTooltipSpecValue() { console.log('hideTooltipSpecValue','----------') this.tooltipVisibleSpecValue = false }, onStart() { this.drag = true }, handleAvatarSuccess(res, file, fileList, index) { this.spuInfo.sku_map_list[index].image = res.data[0].url }, // 添加規(guī)格 addAttr(e, item, index) { if (empty(e.target.value)) { return } this.spuAttrs.push({ attr: e.target.value, values: [''] }) // 判斷this.spuAttrs.attr 是否有空值,如果有空值則刪除 for (let i = 0; i < this.spuAttrs.length; i++) { if (empty(this.spuAttrs[i].attr)) { this.spuAttrs.splice(i, 1) } } }, addBarcode(e, row, index) { this.spuInfo.sku_map_list[index].barcode = e.target.value }, addPrice(e, row, index) { this.spuInfo.sku_map_list[index].price = e.target.value }, addMarketPrice(e, row, index) { this.spuInfo.sku_map_list[index].market_price = e.target.value }, addAttrValue(e, index, vi) { if (empty(e.target.value)) { return } this.attrSkuMap(1, index, this.spuAttrs[index].values.length - 1) }, onEnd() { this.drag = false this.attrSkuMap(3, 0, 0) }, // 選擇規(guī)格名 changeAttr(e, index) { this.spuAttrs[index].values = [''] this.spuAttrs[index].attr = this.cateAttrs[index].label this.attrSkuMap(3, index, -1) }, spuAttrItem(type, index) { if (type === 1) { this.spuAttrs.push({ attr: '', values: [''] }) } else { this.changeType = 1 this.changeContent = this.spuAttrs[index].attr this.spuAttrs.splice(index, 1) } this.attrSkuMap(type, index, type === 1 ? 0 : 1) }, // 添加|刪除規(guī)格值 spuAttrValueItem(type, pIndex, subIndex) { if (type === 1) { this.spuAttrs[pIndex].values.push('') } else { this.changeType = 2 this.changeContent = this.spuAttrs[pIndex].values[subIndex] this.spuAttrs[pIndex].values.splice(subIndex, 1) } this.attrSkuMap(type, pIndex, subIndex) }, // 生成sku組合表格,處理每行數(shù)據(jù)x generateCombinations(type, pIndex, subIndex, changeIndex = 0, spliceIndex = -1, currentCombination = [], index = 0) { if (index >= this.spuAttrs.length) { // 1-新增,2-刪除,3-修改 if (type === 1) { // 頁(yè)面新開 新增的sku情況 if (empty(this.spuInfo.sku_map_list[changeIndex])) { this.spuInfo.sku_map_list.push({ barcode: '', price: '', market_price: '', attrs: [], image: '' }) // attrs 字段與頁(yè)面顯示無(wú)關(guān),只為傳給后端使用 for (let j = 0; j < currentCombination.length; j++) { this.spuInfo.sku_map_list[changeIndex].attrs.push({ attr: currentCombination[j].attr, value: currentCombination[j].value }) } // 頁(yè)面新開 編輯的sku情況 } else if (currentCombination.length === this.spuInfo.sku_map_list[changeIndex].attrs.length) { for (let j = 0; j < currentCombination.length; j++) { this.spuInfo.sku_map_list[changeIndex].attrs[j].attr = currentCombination[j].attr this.spuInfo.sku_map_list[changeIndex].attrs[j].value = currentCombination[j].value } } else if (currentCombination.length > this.spuInfo.sku_map_list[changeIndex].attrs.length) { const item = currentCombination.slice(-1) this.spuInfo.sku_map_list[changeIndex].attrs.push({ attr: item.attr, value: item.value }) } } else if (type === 2) { // 遍歷currentCombination,把value 拼接組合,后面在循環(huán)中刪除多余重復(fù)的行 if (this.changeType === 1) { let currentCombinationValue = '' for (let j = 0; j < currentCombination.length; j++) { currentCombinationValue += currentCombination[j].value + '_' } for (let k = 0; k < this.spuInfo.sku_map_list.length; k++) { if (empty(this.spuInfo.sku_map_list[k])) { continue } for (let j = 0; j < this.spuInfo.sku_map_list[k].attrs.length; j++) { if (empty(this.spuInfo.sku_map_list[k].attrs[j])) { continue } if (this.changeContent === this.spuInfo.sku_map_list[k].attrs[j].attr ) { // 刪除規(guī)格 this.spuInfo.sku_map_list[k].attrs.splice(j, 1) // 組合規(guī)格值 let itemValueCombination = '' for (let m = 0; m < this.spuInfo.sku_map_list[k].attrs.length; m++) { itemValueCombination += this.spuInfo.sku_map_list[k].attrs[m].value + '_' } this.spuInfo.sku_map_list[k].combination = itemValueCombination } } } for (let v = 0; v < this.spuInfo.sku_map_list.length; v++) { let count = 0 if (empty(this.spuInfo.sku_map_list[v])) { continue } if (currentCombinationValue === this.spuInfo.sku_map_list[v].combination) { count++ } // 相同規(guī)格的行只保留一條 if (count > 1) { this.spuInfo.sku_map_list.splice(v, 1) } } } else { for (let k = 0; k < this.spuInfo.sku_map_list.length; k++) { if (empty(this.spuInfo.sku_map_list[k]) || empty(this.spuInfo.sku_map_list[k].attrs)) { continue } const attrs = this.spuInfo.sku_map_list[k]?.attrs || [] for (let j = 0; j < attrs.length; j++) { if (this.empty(attrs[j])) { continue } if (this.changeContent === attrs[j].value) { // 刪除整行 this.spuInfo.sku_map_list.splice(k, 1) break // 如果刪除了當(dāng)前行,需要跳出循環(huán) } } } } } else { for (let j = 0; j < currentCombination.length; j++) { this.spuInfo.sku_map_list[changeIndex].attrs[j].attr = currentCombination[j].attr this.spuInfo.sku_map_list[changeIndex].attrs[j].value = currentCombination[j].value } } changeIndex++ spliceIndex = -1 // return 之后執(zhí)行 this.generateCombinations 的邏輯 return [changeIndex, spliceIndex] } // 規(guī)格和規(guī)格值都遍歷 for (var i = 0; i < this.spuAttrs[index].values.length; i++) { currentCombination.push({ attr: this.spuAttrs[index].attr, value: this.spuAttrs[index].values[i] }) // 假如有 尺寸 S M ,顏色 黃色 白色 // 第一次遍歷生成 {"attr":"尺寸","value":"S"} // 第二次遍歷生成 {"attr":"尺寸","value":"S"},{"attr":"顏色","value":"黃色"}組合,然后在渲染到表格的第一行中 // changeIndex 為行數(shù)或者組合數(shù)量 // generateCombinations 自循環(huán),遇到return [changeIndex, spliceIndex]后才往下執(zhí)行 const res = this.generateCombinations(type, pIndex, subIndex, changeIndex, spliceIndex, currentCombination, index + 1) changeIndex = res[0] spliceIndex = res[1] currentCombination.pop() } return [changeIndex, spliceIndex] }, attrSkuMap(type, pIndex, subIndex) { this.generateCombinations(type, pIndex, subIndex) return }, getAttrValue(item, i) { return item.attrs[i].value }, async saveSpu() { return await saveSpu(this.spuInfo) } } } </script> <style scoped lang="scss"> .cate_level1 { color: #E6A23C; } .attr_select_index { margin-bottom: 14px; } .attr_options_add, .attr_val_options_add { margin-left: -2px; font-size: 20px; color: #409EFF; cursor: pointer; } .item { padding: 3px; //background-color: #fdfdfd; //border: solid 1px #eee; margin-bottom: 10px; cursor: move; } .item:hover { background-color: #f1f1f1; cursor: move; } .chosen { border: solid 2px #3089dc !important; } .attr_options_del, .attr_val_options_del { margin-left: -2px; font-size: 20px; color: #F56C6C; cursor: pointer; } .tooltip-container { position: relative; display: inline-block; } .tooltip-text { visibility: visible; width: 120px; background-color: black; color: #fff; text-align: center; border-radius: 6px; padding: 5px 0; position: absolute; z-index: 1; bottom: 125%; /* Position the tooltip above the icon */ left: 50%; margin-left: -60px; opacity: 0; transition: opacity 0.3s; } .tooltip-container:hover .tooltip-text { visibility: visible; opacity: 1; } .avatar-uploader .el-upload { border: 1px dashed #d9d9d9; border-radius: 6px; cursor: pointer; position: relative; overflow: hidden; } .avatar-uploader .el-upload:hover { border-color: #409EFF; } .avatar-uploader-icon { font-size: 28px; color: #8c939d; width: 30px; height: 30px; line-height: 30px; text-align: center; } .avatar { width: 30px; height: 30px; display: block; } </style>
數(shù)據(jù)結(jié)構(gòu)
{ "msg": "ok", "code": 10000, "data": { "id": "710432902999261184", "goods_name": "spu測(cè)試ywz", "cate_code": "Lthg98", "brand_code": "UpsPhd", "supplier_code": "", "audit_status": 1, "pack_spec": "101", "pack_count": "102", "unit_name": "103", "expire_date": "2024-10-24", "images": [ "https:\/\/img-hyg.hltmsp.com\/member\/image\/20240918\/c7865c97174a4eb92519edd42a98af74851785.png", "https:\/\/img-hyg.hltmsp.com\/member\/image\/20240918\/4508beb29e17b950796cc5961a88b520299817.png" ], "video": "", "video_cover": "", "is_show_video": 1, "description": "<p>spu測(cè)試spu測(cè)試spu測(cè)試<\/p>", "sort": 0, "is_gift": 1, "goods_type": 1, "sales_count": 0, "is_sales_amount_limit": 1, "recommendation": "spu測(cè)試spu測(cè)試spu測(cè)試", "is_search": 1, "is_pre_sales": 1, "is_expire": 1, "is_suite": 1, "merchant_id": 1, "business_type": 1, "keep_desc_tpl_id": 2, "notice_desc_tpl_id": 0, "del_status": 1, "create_time": "2024-10-31 10:06:43", "update_time": "2024-10-31 10:06:43", "sku_map_list": [ { "id": 710432903292862464, "spu_id": "710432902999261184", "goods_code": "", "barcode": "spu_1234561345678ywz1", "image": "https:\/\/img-hyg.hltmsp.com\/member\/image\/20240918\/c7865c97174a4eb92519edd42a98af74851785.png", "search_weight": 0, "sort": 0, "sales_count": 0, "price": "99.00", "market_price": "199.00", "cost_price": "0.00", "create_time": "2024-10-31 10:06:43", "update_time": "2024-10-31 10:06:43", "attrs": [ { "attr": "尺寸", "value": "尺寸1" }, { "attr": "顏色", "value": "顏色1" } ] }, { "id": 710432903292862465, "spu_id": "710432902999261184", "goods_code": "", "barcode": "spu_12345631345678ywz1", "image": "https:\/\/img-hyg.hltmsp.com\/member\/image\/20240918\/c7865c97174a4eb92519edd42a98af74851785.png", "search_weight": 0, "sort": 0, "sales_count": 0, "price": "99.00", "market_price": "199.00", "cost_price": "0.00", "create_time": "2024-10-31 10:06:43", "update_time": "2024-10-31 10:06:43", "attrs": [ { "attr": "尺寸", "value": "尺寸1" }, { "attr": "顏色", "value": "顏色2" } ] }, { "id": 710432903292862466, "spu_id": "710432902999261184", "goods_code": "", "barcode": "spu_123456451345678ywz1", "image": "https:\/\/img-hyg.hltmsp.com\/member\/image\/20240918\/c7865c97174a4eb92519edd42a98af74851785.png", "search_weight": 0, "sort": 0, "sales_count": 0, "price": "99.00", "market_price": "199.00", "cost_price": "0.00", "create_time": "2024-10-31 10:06:43", "update_time": "2024-10-31 10:06:43", "attrs": [ { "attr": "尺寸", "value": "尺寸2" }, { "attr": "顏色", "value": "顏色1" } ] }, { "id": 710432903292862467, "spu_id": "710432902999261184", "goods_code": "", "barcode": "spu_123456561345678ywz1", "image": "https:\/\/img-hyg.hltmsp.com\/member\/image\/20240918\/c7865c97174a4eb92519edd42a98af74851785.png", "search_weight": 0, "sort": 0, "sales_count": 0, "price": "99.00", "market_price": "199.00", "cost_price": "0.00", "create_time": "2024-10-31 10:06:43", "update_time": "2024-10-31 10:06:43", "attrs": [ { "attr": "尺寸", "value": "尺寸2" }, { "attr": "顏色", "value": "顏色2" } ] } ], "spu_attrs": [ { "attr": "尺寸", "values": [ "尺寸1", "尺寸2" ] }, { "attr": "顏色", "values": [ "顏色1", "顏色2" ] } ] }, "log_id": "710498316961951744" }
到此這篇關(guān)于element根據(jù)輸入,動(dòng)態(tài)生成表格的文章就介紹到這了,更多相關(guān)element動(dòng)態(tài)生成表格內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- element el-table如何實(shí)現(xiàn)表格動(dòng)態(tài)增加/刪除/編輯表格行(帶校驗(yàn)規(guī)則)
- Vue+ElementUI踩坑之動(dòng)態(tài)顯示/隱藏表格的列el-table-column問(wèn)題
- element-ui復(fù)雜table表格動(dòng)態(tài)新增列、動(dòng)態(tài)調(diào)整行以及列順序詳解
- vue element-ui表格自定義動(dòng)態(tài)列具體實(shí)現(xiàn)
- el-element中el-table表格嵌套el-select實(shí)現(xiàn)動(dòng)態(tài)選擇對(duì)應(yīng)值功能
- vue?element-ui動(dòng)態(tài)橫向統(tǒng)計(jì)表格的實(shí)現(xiàn)
- element表格行列的動(dòng)態(tài)合并示例詳解
- element 動(dòng)態(tài)合并表格的步驟
- Vue+elementui 實(shí)現(xiàn)復(fù)雜表頭和動(dòng)態(tài)增加列的二維表格功能
相關(guān)文章
警告[vue-router]?Duplicate?named?routes?definition簡(jiǎn)單解決方法
這篇文章主要關(guān)于介紹了警告[vue-router]?Duplicate?named?routes?definition的解決方法,這個(gè)錯(cuò)誤提示是因?yàn)樵赩ue Router中定義了重復(fù)的路由名稱,需要的朋友可以參考下2023-12-12對(duì)vue中的input輸入框進(jìn)行郵箱驗(yàn)證方式
這篇文章主要介紹了對(duì)vue中的input輸入框進(jìn)行郵箱驗(yàn)證方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10解決Vue使用swiper動(dòng)態(tài)加載數(shù)據(jù),動(dòng)態(tài)輪播數(shù)據(jù)顯示白屏的問(wèn)題
今天小編就為大家分享一篇解決Vue使用swiper動(dòng)態(tài)加載數(shù)據(jù),動(dòng)態(tài)輪播數(shù)據(jù)顯示白屏的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09Vue向下滾動(dòng)加載更多數(shù)據(jù)scroll案例詳解
這篇文章主要介紹了Vue向下滾動(dòng)加載更多數(shù)據(jù)scroll案例詳解,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08vue中table表頭單元格合并(附單行、多級(jí)表頭代碼)
本文主要介紹了vue中table表頭單元格合并(附單行、多級(jí)表頭代碼),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04Vue 動(dòng)態(tài)添加表單實(shí)現(xiàn)動(dòng)態(tài)雙向綁定
動(dòng)態(tài)表單是一個(gè)常見的需求,本文詳細(xì)介紹了Vue.js中實(shí)現(xiàn)動(dòng)態(tài)表單的創(chuàng)建,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-12-12