利用ElementUI配置商品的规格参数
需求:商品可以设置多个规格,需要自动生成对应规格的所有组合,并设置该规格商品的图片、价格、库存等数据。
<template>
<div class="sku-list">
<template v-if="!disabled">
<div class="sku-list-head">
<el-button type="primary" size="mini" @click="addSkuRow"
>添加规格</el-button
>
</div>
<div
class="sku-list-item"
v-for="(item, index) in skuData.attrList"
:key="index"
>
<div class="sku-list-item-main">
<div class="sku-list-item__layout">
<span class="span">规格名</span>
<el-input
size="small"
v-model="item.attrName"
class="input"
></el-input>
</div>
<div class="sku-list-item__layout">
<span class="span">规格值</span>
<div class="sku-list-item-tags">
<el-tag
class="sku-list-item-tag"
closable
@close="removeSkuAttr(index, i)"
v-for="(subitem, i) in item.attrValue"
:key="i"
>{{ subitem.attrValue }}</el-tag
>
<el-button
size="small"
icon="el-icon-plus"
@click="addSkuAttr(index)"
>添加</el-button
>
</div>
</div>
</div>
<el-button
type="text"
size="small"
class="sku-list-item-removeBtn"
@click="removeSkuRow(index)"
>删除规格</el-button
>
</div>
</template>
<el-table border :data="skuData.skuList">
<el-table-column label="规格图片" align="center" width="120">
</el-table-column>
<el-table-column
label="规格名称"
align="center"
prop="attrPath"
></el-table-column>
<el-table-column label="规格售价" align="center">
<template slot-scope="scope">
<el-input-number v-model="scope.row.priceCost" :precision="2" :min="0.01"/>
</template>
</el-table-column>
<!-- <el-table-column label="销售价格" align="center">-->
<!-- <template slot-scope="scope">-->
<!-- <el-input-->
<!-- :readonly="disabled"-->
<!-- v-model="scope.row.priceCash"-->
<!-- ></el-input>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="划线价格" align="center">-->
<!-- <template slot-scope="scope">-->
<!-- <el-input-->
<!-- :readonly="disabled"-->
<!-- v-model="scope.row.priceOriginal"-->
<!-- ></el-input>-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="规格库存" align="center">
<template slot-scope="scope">
<el-input-number v-model="scope.row.stock" :min="0" :max="999999"/>
</template>
</el-table-column>
<!-- <el-table-column label="商品预警值" align="center">
<template slot-scope="scope">
<el-input :readonly="disabled" v-model="scope.row.stock"></el-input>
</template>
</el-table-column> -->
<!-- <el-table-column v-if="!disabled" label="操作" align="center">
<template>
<el-button type="text" size="small">删除</el-button>
<el-button type="text" size="small">上移</el-button>
</template>
</el-table-column> -->
</el-table>
</div>
</template>
<script>
export default {
model: {
prop: "skuData",
event: "changeSku",
},
props: {
// skuData: {
// type: Object,
// default: () => ({}),
// },
disabled: {
type: Boolean,
default: false,
},
},
data() {
return {
skuData: {
attrList: [],
skuList: [],
initSkuList: []
}
};
},
watch: {
"skuData.attrList": {
handler() {
if (!this.disabled) {
this.$set(this.skuData, "skuList", this.getTable());
}
},
deep: true,
immediate: true,
},
},
methods: {
// 添加规格行
addSkuRow(i) {
// const attrList = this.skuData.attrList;
// if (attrList === undefined) {
// const list = [{
// attrName: "",
// attrValue: []
// }]
// this.skuData.attrList = list;
// } else {
// attrList.push({
// attrName: "",
// attrValue: []
// });
// }
this.skuData.attrList.push({
attrName: "",
attrValue: []
})
this.$emit("changeSku", this.skuData);
},
// 删除规格行
removeSkuRow(i) {
this.skuData.attrList.splice(i, 1);
this.$emit("changeSku", this.skuData);
},
// 删除规格属性值
removeSkuAttr(a, b) {
this.skuData.attrList[a].attrValue.splice(b, 1);
this.$emit("changeSku", this.skuData);
},
// 添加规格属性值
addSkuAttr(i) {
this.$prompt("请输入规格值", "添加规格值", {
confirmButtonText: "确定",
cancelButtonText: "取消",
inputPattern: /\S+/,
inputErrorMessage: "规格值不能为空",
closeOnClickModal: false,
}).then(({ value }) => {
this.skuData.attrList[i].attrValue.push({
attrValue: value,
});
this.$emit("changeSku", this.skuData);
});
},
onUploadImgSuccess(res, file, row) {
if (!file) {
return;
}
row.icon = file;
this.$emit("changeSku", this.skuData);
},
getTable() {
const table = [];
const attrValueAry = [];
const arr = [];
const tmpSkuData = (this.skuData.attrList || []).filter(
(d) => d.attrName !== "" && d.attrValue.length > 0
);
if (!tmpSkuData || tmpSkuData.length === 0) {
return [];
}
tmpSkuData.forEach((item) => {
attrValueAry.push(item.attrValue);
});
function func(skuArr = [], i) {
for (let j = 0; j < attrValueAry[i].length; j++) {
if (i < attrValueAry.length - 1) {
skuArr[i] = attrValueAry[i][j];
func(skuArr, i + 1);
} else {
arr.push([...skuArr, attrValueAry[i][j]]);
}
}
}
func([], 0);
arr.forEach((item) => {
let attrPath = "";
// const findItem = {};
// const tableItem = {};
item.forEach((d, idx) => {
attrPath += `${tmpSkuData[idx].attrName}:${d.attrValue};`;
});
attrPath = attrPath.slice(0, attrPath.length - 1);
const findItem =
this.skuData.initSkuList.find((item) => {
return attrPath.includes(item.attrPath);
}) || {};
const tableItem = Object.assign(
{
priceCost: 0,
priceCash: 0,
priceOriginal: 0,
stock: 0,
icon: null,
},
findItem,
{
attrPath,
}
);
table.push(tableItem);
});
return table;
},
},
};
</script>
<style lang="scss" scoped>
.sku-list {
&-head {
margin-bottom: 10px;
}
&-item {
display: flex;
align-items: center;
border: 1px solid #eee;
border-radius: 5px;
margin-bottom: 20px;
padding: 20px 50px;
&-main {
flex: 1;
}
&-removeBtn {
margin-left: 20px;
color: #f56c6c;
}
&__layout {
display: flex;
align-items: center;
margin-bottom: 20px;
&:last-child {
margin-bottom: 0;
}
.input {
width: 240px;
}
.span {
font-size: 13px;
font-weight: bold;
margin-right: 10px;
}
}
&-tags {
flex: 1;
}
&-tag {
margin-bottom: 10px;
margin-right: 10px;
}
}
}
</style>