刚看到后台传的数据的时候,那个头啊真是一个头两个大。
查询了百度后就开始有了灵感和思路了,下面就来看看实现的效果吧,这个是vue+element-ui的后台管理系统,用到的是element的ui。
-这是后端传的商品,不要对商品图片太在意
灰色的都是无法点中的
image.png
image.png
image.png
-我们看到在这张图片就有了价格和库存了,这就是效果的实现了,不同的规格选择的商品都是不一样的
image.png
这是后台传来的sku的数据,itemSku这个就是对应规格的数组,每一个数组对象都有一个stock库存,price价格。
image.png
接着我们就来用代码来实现吧!
<el-button @click="_slectSpecification"></el-button>
<!-- 上面是每个商品的按钮选择规格 -->
<el-dialog width="40%" :visible.sync="specificVisible" title="选择规格" class="selectSpe">
<div class="selectSpe__main">
<div class="selectSpe__main__top">
<div class="selectSpe__main__top__left">
<img :src="goodslist.bigImage" alt>
</div>
<div class="selectSpe__main__top__right">
<p class="title">{{ goodslist.goodsNames }}</p>
<div class="shopBox">
<span>¥ {{ newPrice || '--' }}</span>
<span>库存:{{ newStock || '--' }}</span>
</div>
</div>
</div>
<div class="selectSpe__main__bottom">
<div
v-for="(item,index) in skuData"
:key="`item${index}`"
class="selectSpe__main__bottom__item"
>
<p>{{ item.name }}</p>
<div class="ratio">
<div
v-for="(childItem,childIndex) in item.child"
:key="`childItem${childIndex}`"
class="item"
:class="[childItem.isShow?'':'noneActive', subIndex[index] == childIndex?'productActive':'']"
@click="_changeChildSelect(childItem.id,index, $event,childIndex)"
>{{ childItem.name }}</div>
</div>
</div>
</div>
</div>
</el-dialog>
.selectSpe{
&__main{
&__top{
display: flex;
align-items: center;
&__left{
flex: 0.3;
margin-right: 20px;
img{
width: 100%;
height: 100%;
}
}
&__right{
flex: 1;
// text-align: center;
.title{
color: #333;
font-size: 12px;
line-height: 15px;
}
.shopBox{
margin-top: 20px;
display: flex;
color: #333;
font-size: 14px;
span{
&:first-child{
margin-right: 20px;
}
}
}
}
}
&__bottom{
.ratio{
display: flex;
.item{
width: 90px;
height: 40px;
line-height: 40px;
font-size: 12px;
color: #333;
text-align: center;
border-radius: 5px;
border: 1px solid #eee;
margin-right: 20px;
transition: all 0.25s ease-in-out;
cursor: pointer;
}
.productActive{
background-color: #409EFF;
color: #fff;
border: none;
}
.noneActive{
background-color: #ccc;
opacity: 0.4;
color: #000;
pointer-events: none;
}
}
}
}
}
-接着我们就来定义data里面的数据
data() {
return {
specificVisible: false,
//里面的数据根据后台返回,图片上有
goodslist: {
bigImage: "http://h.hiphotos.baidu.com/image/pic/item/7c1ed21b0ef41bd5f2c2a9e953da81cb39db3d1d.jpg",
goodsNames: "测试商品1",
itemKey: [],
itemSku: [],
itemVal: [],
},
// 存放要和选中的值进行匹配的数据
shopItemInfo: {},
// 选中规格的价钱
newPrice: '--',
newStock: '--',
newSkuId: '',
// 存放被选中的值
selectArr: [],
skuData: [],
// 是否选中 因为不确定是多规格还是单规格,所以这里定义数组来判断
subIndex: [],
skuResult: [],
}
}
下面定义方法显示sku
//注意这里,我是假设res.result的数据就是定义的goodslist的数据,具体数据以实际情况而定
_slectSpecification(res){
this.specificVisible = true
this.shopItemInfo = {}
this.subIndex = []
this.selectArr = []
this.newPrice = '--'
this.newStock = '--'
this.newSkuId = ''
this.goodslist = res.result
const itemKey = res.result.itemKey || []
const itemVal = res.result.itemVal || []
itemKey.length > 0 &&
itemKey.forEach(item => {
// console.log(item)
item.child = []
itemVal.forEach(childItem => {
if (childItem.keyId === item.id) {
item.child.push(childItem)
}
})
})
this.skuData = itemKey
for (var i in res.result.itemSku) {
this.shopItemInfo[res.result.itemSku[i].itemId] = res.result.itemSku[i] // 修改数据结构格式,改成键值对的方式,以方便和选中之后的值进行匹配
}
this.checkItem()
},
// 选中规格触发
_changeChildSelect(childItem, index, $event, childIndex) {
var self = this
if (self.selectArr[index] !== childItem) {
self.selectArr[index] = childItem
self.subIndex[index] = childIndex
} else {
self.selectArr[index] = ''
self.subIndex[index] = -1 // 去掉选中的颜色
}
self.checkItem()
// this.selectChildItem = childItem.id
},
checkItem: function() {
var self = this
var option = self.skuData
this.skuResult = [] // 定义数组储存被选中的值
for (var i in option) {
this.skuResult[i] = self.selectArr[i] ? self.selectArr[i] : ''
}
for (var j in option) {
var last = this.skuResult[j] // 把选中的值存放到字符串last去
for (var k in option[j].child) {
this.skuResult[j] = option[j].child[k].id // 赋值,存在直接覆盖,不存在往里面添加name值
option[j].child[k].isShow = self.isMay(this.skuResult) // 在数据里面添加字段isShow来判断是否可以选择
}
this.skuResult[j] = last // 还原,目的是记录点下去那个值,避免下一次执行循环时被覆盖
}
// console.log('-----------')
// console.log(result)
// console.log(this.shopItemInfo)
// console.log(this.shopItemInfo[result])
// console.log('-----------')
if (this.shopItemInfo[this.skuResult]) {
this.newPrice = this.shopItemInfo[this.skuResult].price || '--'
} else {
this.newPrice = '--'
}
if (this.shopItemInfo[this.skuResult]) {
this.newStock = this.shopItemInfo[this.skuResult].stock || '--'
} else {
this.newStock = '--'
}
if (this.shopItemInfo[this.skuResult]) {
this.newSkuId = this.shopItemInfo[this.skuResult].id || ''
} else {
this.newSkuId = ''
}
self.$forceUpdate() // 重绘
},
isMay: function(result) {
for (var i in result) {
if (result[i] === '') {
return true // 如果数组里有为空的值,那直接返回true
}
}
// console.log('shopItemInfo', this.shopItemInfo[result])
if (this.shopItemInfo[result]) {
return this.shopItemInfo[result].stock !== 0 // 匹配选中的数据的库存,若不为空返回true反之返回false
}
return false
},
原创文章:https://www.jb51.net/article/168283.htm
感谢这篇文章的帮助,修改下就有了自己的商品sku规格的实现。
希望能帮到大家!
网友评论