vue sku商品规格模板之后台管理系统篇
2020-08-29 本文已影响0人
MrHong_bfea
刚看到设计稿的时候,还是有点懵的,查询了百度后就开始有了灵感和思路了,下面就来看看实现的效果吧,这个是vue+element-ui的后台管理系统,用到的是element的ui。
前面步骤一到二是上传图片,第三步才是商品sku模板的开始。
1.下图是我们看到模板的第一步(添加规格类型),就是不论什么规格都是自己拟定义
image.png
2.下图是我们看到的第二步,增加规格的名称
image.png
image.png
3.下图是我们看到的增加的sku,要多少规格名称和规格的sku都自己拟定就OK拉!
image.png
image.png
4.这是第三步点击下一步后的第四步,也就是生成了sku的模板了,我们可以在后面输入该规格的库存和价格,当然这个库存和价格都是可以自己拟定的。
image.png
5.下面就来看一下代码的演示效果吧!
-这是第三步和第四步的html代码
<div v-show="shopStepActive==3" class="stepThird" style="width:100%">
<el-button
type="primary"
icon="el-icon-circle-plus"
class="addSpecificaType"
@click="_addSpecifoca"
>添加规格类型</el-button>
<div v-for="(item,index) in templateData" :key="`item${index}`" class="itemTag">
<div class="outerBorder">
<div class="close" @click="_deleteTemplateData(index)">
<i class="el-icon-error" />
</div>
<div class="inputMar">
<el-input v-model="item.name" placeholder="请输入规格名称,如尺寸;" style="width:300px" />
<!-- <el-button type="primary" @click="_addSizeName">添加</el-button> -->
</div>
<div v-show="item.name">
<el-tag
v-for="tag in item.dynamicTags"
:key="`${tag}index`"
closable
:disable-transitions="false"
@close="handleClose(tag, item)"
>{{ tag }}</el-tag>
<el-input
v-if="item.tagInputVisible"
:ref="'saveTagInput'+index"
v-model="item.tagInputValue"
v-focus="item.focusState"
class="input-new-tag"
size="small"
@keyup.enter.native="handleInputConfirm(item, index)"
@blur="handleInputConfirm(item, index)"
/>
<el-button
v-else
class="button-new-tag"
size="small"
@click="_addshowInput(item, index)"
>+ {{ item.name }}</el-button>
</div>
</div>
</div>
</div>
<div v-show="shopStepActive==4" class="stepFour">
<div class="stepFour__name">
<div
v-for="(nameItem,nameIndex) in templateNameList"
:key="`nameItem${nameIndex}`"
class="item"
>{{ nameItem }}</div>
</div>
<div v-show="newTemplateData.length>0" class="stepFour__box">
<div
v-for="(item,index) in newTemplateData"
:key="`item${index}`"
class="stepFour__box__panel"
>
<div
v-for="(childItem,childIndex) in item"
:key="`childItem${childIndex}`"
class="item"
>
<span
v-show="childIndex!=(item.length-1) && childIndex!=(item.length-2)"
>{{ childItem }}</span>
<el-input
v-show="childIndex==(item.length-2)"
v-model="childItem.stockNum"
oninput="value=value.replace(/[^\d.]/g,'')"
placeholder="输入库存"
style="width:100%"
/>
<el-input
v-show="childIndex==(item.length-1)"
v-model="childItem.price"
oninput="value=value.replace(/[^\d.]/g,'')"
placeholder="输入价格"
style="width:100%"
/>
</div>
</div>
</div>
</div>
<div class="rigEnd">
<el-button
v-show="shopStepActive!=1"
type="text"
class="previousBtn"
@click="_previousStep"
>上一步</el-button>
<el-button v-show="shopStepActive!=4" type="primary" class="saveBtn" @click="_nextStep">下一步</el-button>
<el-button
v-show="shopStepActive==4"
type="primary"
class="saveBtn"
@click="_saveTemplate"
>保存</el-button>
</div>
-下面是scss的代码,样式可自行修改
.stepThird{
.addSpecificaType{
margin-bottom: 10px;
}
.itemTag{
margin-bottom: 20px;
.outerBorder{
width: 100%;
border: 1px solid #eee;
border-radius: 5px;
padding: 10px;
box-sizing: border-box;
position: relative;
.close{
position: absolute;
right: 0;
top: 0;
i{
font-size: 20px;
cursor: pointer;
}
}
.inputMar{
margin-bottom: 10px;
}
}
}
}
.stepFour{
width: 100%;
margin: auto;
&__name{
width: 100%;
box-sizing: border-box;
border: 1px solid #eee;
display: flex;
align-items: center;
.item{
flex: 1;
width: 120px;
height: 50px;
line-height: 50px;
text-align: center;
font-size: 14px;
border-right: 1px solid #eee;
padding: 0 10px;
box-sizing: border-box;
}
}
&__box{
&__panel{
width: 100%;
box-sizing: border-box;
border: 1px solid #eee;
display: flex;
align-items: center;
.item{
flex: 1;
width: 120px;
height: 50px;
line-height: 50px;
text-align: center;
font-size: 14px;
border-right: 1px solid #eee;
padding: 0 10px;
box-sizing: border-box;
}
}
}
}
.rigEnd {
display: flex;
justify-content: flex-end;
.previousBtn{
color: #333;
margin-right: 20px;
}
.saveBtn{
width: 200px;
height: 46px;
}
}
-就着我们来定义变量
//自定义指令v-focus
directives: {
focus: {
// 根据focusState的状态改变是否聚焦focus
update: function(el, value) {
// 第二个参数传进来的是个json
if (value) {
el.focus()
}
}
}
},
data(){
return {
//步骤
shopStepActive: 3,
//每一个sku规格的数据
templateData: [],
// 每一个sku规格里面拟定的数据如:颜色里面的[红色,蓝色,黄色]这些
dynamicTags: [],
// 这个是第四步步骤里的for循环的颜色的模板名称,如[颜色,尺寸,库存,价格]
templateNameList: []
// 这个是第四步步骤里的for循环的数据,如[红色,S,11个,56元]
newTemplateData: []
}
}
-接着就是我们需要定义方法处理数据了
// 添加规格类型
_addSpecifoca() {
this.templateData.push({
name: '',
dynamicTags: [],
tagInputVisible: false,
tagInputValue: '',
focusState: false
})
},
// 删除商品规格
_deleteTemplateData(index) {
this.templateData.splice(index, 1)
},
// 删除单个标签
handleClose(tag, item) {
item.dynamicTags.splice(item.dynamicTags.indexOf(tag), 1)
},
// 按下enter或者失去焦点的时候触发Input里面的值到<el-tag>
handleInputConfirm(item, index) {
const tagInputValue = item.tagInputValue
if (tagInputValue) {
if (item.dynamicTags.indexOf(tagInputValue) === -1) {
item.dynamicTags.push(tagInputValue)
} else {
Message.warning('请勿重复输入')
}
}
item.tagInputVisible = false
item.tagInputValue = ''
},
// 点击变成输入框
_addshowInput(item, index) {
item.tagInputVisible = true
this.$nextTick(() => {
item.focusState = true
// this.$refs.saveTagInput[index].$refs.input.focus()
})
},
// 多数组求笛卡儿积function cartesianProduct(array){
recursionData(array) {
return array.reduce(
function(a, b) {
return a
.map(function(x) {
return b.map(function(y) {
return x.concat(y)
})
})
.reduce(function(a, b) {
return a.concat(b)
}, [])
},
[[]]
)
},
// 下一步步骤
_nextStep() {
this.newTemplateData = []
this.templateNameList = []
this.shopStepActive++
const array = []
if (this.shopStepActive === 4) {
this.templateData.forEach(element => {
this.templateNameList.push(element.name)
array.push(element.dynamicTags)
})
this.newTemplateData = this.recursionData(array).filter(item => {
item.push({ stockNum: '' }, { price: '' })
return item
})
console.log(this.newTemplateData)
this.templateNameList.push('库存', '价格')
}
},
// 上一步
_previousStep() {
this.shopStepActive--
}
-最后一个保存的方法是看下后台需要我们传的数据,首先我们来看看后台需要我们传的数据是什么
"sku":[
{
"price":"1000.00",
"stock":"100",
"item_id":[{"keyName": "颜色","keyVal": "白色"},{"keyName": "内存","keyVal": "128G"}]
},
{
"price":"3000.00",
"stock":"80",
"item_id":[{"keyName": "颜色","keyVal": "黑色"},{"keyName": "内存","keyVal": "512G"}]
},
{
"price":"3000.00",
"stock":"50",
"item_id":[{"keyName": "颜色","keyVal": "蓝色"},{"keyName": "内存","keyVal": "1024G"}]
}
]
-最后我们再编写一个方法来完成保存需要给的后台的数据
// 保存添加的模板
_saveTemplate() {
var newVal = []
const sku = this.newTemplateData.reduce((c, item) => {
newVal = []
for (let k = 0; k < item.length - 2; k++) {
newVal.push({
keyName: [...this.templateNameList][k],
keyVal: item[k]
})
}
return c.concat({
price: item[item.length - 1].price,
stockNum: item[item.length - 2].stockNum,
item_id: [...newVal]
})
}, [])
console.log(sku)
},
大功告成,每个方法都有注释,就不全部介绍了,这就是我们的Vue+element的sku商品规格模板。只要思路清晰了,就可以搞,加油。
最后希望能帮到大家。