电商需求-商品规格组件,使用到了oss-upload组件(在vue文集下的ossUpload一文)
效果图
<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)"
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">
<template slot-scope="scope">
<oss-upload
:disabled="disabled"
:on-success="
(res, file) => onUploadImgSuccess(res, file, scope.row)
"
dir="erp/goods"
>
<img
v-if="scope.row.icon"
:src="scope.row.icon"
class="goods-img"
/>
<el-button v-else-if="!disabled" type="text" size="small"
>上传图片</el-button
>
</oss-upload>
</template>
</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
:readonly="disabled"
v-model="scope.row.priceCost"
></el-input>
</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 :readonly="disabled" v-model="scope.row.stock"></el-input>
</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: "change",
},
props: {
skuData: {
type: Object,
default: () => ({}),
},
disabled: {
type: Boolean,
default: false,
},
},
data() {
return {};
},
watch: {
"skuData.attrList": {
handler() {
if (!this.disabled) {
this.$set(this.skuData, "skuList", this.getTable());
}
},
deep: true,
immediate: true,
},
},
methods: {
// 添加规格行
addSkuRow(i) {
this.skuData.attrList.push({
attrName: "",
attrValue: [],
});
this.$emit("change", this.skuData);
},
// 删除规格行
removeSkuRow(i) {
this.skuData.attrList.splice(i, 1);
this.$emit("change", this.skuData);
},
// 删除规格属性值
removeSkuAttr(a, b) {
this.skuData.attrList[a].attrValue.splice(b, 1);
this.$emit("change", 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("change", this.skuData);
});
},
onUploadImgSuccess(res, file, row) {
if (!file) {
return;
}
row.icon = file;
this.$emit("change", 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 = "",
findItem,
tableItem;
item.forEach((d, idx) => {
attrPath += `${tmpSkuData[idx].attrName}:${d.attrValue};`;
});
findItem =
this.skuData.initSkulist.find((item) => {
return attrPath.includes(item.attrPath);
}) || {};
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>
使用的话是这样的
<goods-sku :disabled="isLook" v-model="skuData"></goods-sku>
export default {
data(){
return {
isLook: false,
skuData: {
attrList: [],
skuList: [],
initSkulist: [],
}
}
}
}