根据需求要类似淘宝app的购物车实现。网上的例子一般都是一个产品列表就完成,但淘宝这些需要有一个对店铺的分类,所以复杂度提升一倍。

1.对单个商品数量进行操作的时候,商品的价格变动,总价变动
2.点击产品选择,总价和数量变动,并且一个商店所以产品被选择时,商店的按钮为被选择状态
3.对一个商店做选择的时候,下面所有商品被选择,总价和数量变动,并且所有商店被选择的时,全选为被选择状态
4.全选的时候,所有店铺已经商品为被选择状态,总价和数量变动
<ul>
<li v-for="item in carts">
<div class="shoptitle">
<!--选择商店的全部商品-->
<span class="check" :class="{'checked':item.checked}" @click="checkShop(item)"></span>
{{item.shopTitle}}
</div>
<div class="productlist">
<ul>
<li v-for="pros in item.productList">
<!--选择商品-->
<span class="check" :class="{'checked':pros.isChecked}" @click="ischeck(item,pros)">
</span>
<img src="" alt="" />
<div class="product">
<p class="producttitle">{{pros.productTitle}}</p>
<p class="category">{{pros.category}}</p>
<div class="price">
<!--使用过滤器对总价改变-->
<span>¥{{pros.price | totalprice(pros.count)}}</span>
<div class="count">
<!--商品数量控制-->
<a herf="javascript:void(0)" class="btn-minus" @click="changeCount(pros,-1)">-</a>
<input type="number" v-model="pros.count">
<a herf="javascript:void(0)" class="btn-plus" @click="changeCount(pros,1)">+</a>
</div>
</div>
</div>
</li>
</ul>
</div>
</li>
</ul>
<div class="paybox">
<div class="payleft">
<!--选择全部商品-->
<span class="check" :class="{'checked':isCheckAll}" @click="checkAll()"></span>
<b>全选</b>
</div>
<button>结算({{allCount}})</button>
<span>总计:{{allPrice}}</span>
</div>
👆自己手写的布局,大概这个样子,主要是双重循环,对几个span的点击事件
carts:[
{
shopTitle:'苹果旗舰店',//商店名
checked:false,//商店选择的状态
checkedCount:0,//此商店被选择的商品数量
productList:[
{
isChecked:false,//商品选择状态
productTitle:'2019款macbook/苹果/MF893/A国航笔记本',//产品名
category:'15寸/2.3/8G/256/土豪金/标准套餐',
price:10200,//价格
count:1//数量
}
]
},
{
shopTitle:'锤子科技旗舰店',
checked:false,
checkedCount:0,
productList:[
{
isChecked:false,
productTitle:'锤子手机手感保护膜',
category:'登陆月球',
price:9.9,
count:1
},
{
isChecked:false,
productTitle:'锤子手机pro割手版',
category:'128G/割手版',
price:1790,
count:1
}
]
}
],
isCheckAll:false,//是否全选
allPrice:0,//所有价格
allShops:0,//被选中的商店数量
allCount:0,//被选中的产品数量
👆先看数据,直接在data模拟的数据
changeCount(val,way){//判断way的值为1还是-1
if (way>0){
val.count++
}else{
val.count--
if(val.count<1){
val.count = 1
}
}
}
filters:{//单件商品的价格 × 数量
totalprice(val,count){
return val * count
}
}
👆一个changeCount
方法来改变商品数量,并用过滤器来返回单个商品的总价
ischeck(item,pro){//为未选中的时候改变为true,反之为true
!pro.isChecked?this._checkTrue(item,pro):this._checkFalse(item,pro)
},
_checkTrue(item,pro){
pro.isChecked = true//改变状态为true
++item.checkedCount == item.productList.length?item.checked = true:''
//每选中一个商品,被选中的商品数加一,如果数值等于商品数,商店的全选状态为true
item.checked? ++this.allShops === this.carts.length ? this.isCheckAll = true : this.isCheckAll = false : ''
//当商店全选状态,每全选一个商店,被选中商店数加一,数值等于所有商店数,全选状态为true
},
_checkFalse(item,pro){
pro.isChecked = false//改变状态为false
--item.checkedCount//被选中的商品数减一
if(item.checked){
item.checked = false//当商店状态为选中时改变false
--this.allShops//商店数减一
}
this.isCheckAll = false//全选状态为false
}
👆选择单个商品
checkShop(item){//与单选商品类似
!item.checked ? this._shopTrue(item) : this._shopFalse(item)
},
_shopTrue(item){//遍历商店每一个商品,状态为false的改变为true,又在_checkTrue()方法中将商店状态改为true
item.productList.forEach((pro)=>{
pro.isChecked === false ? this._checkTrue(item,pro) : ''
})
},
_shopFalse(item){
item.productList.forEach((pro)=>{//同上
pro.isChecked === true ? this._checkFalse(item,pro) : ''
})
}
👆选择整个商店的商品
checkAll(){//方法内调用方法
this.isCheckAll = !this.isCheckAll
this.isCheckAll?
this.carts.forEach((item)=>{this._shopTrue(item)}):
this.carts.forEach((item)=>{this._shopFalse(item)})
},
_totalPeice(){//每次调用此方法,将初始值为0,遍历价格并累加
this.allPrice = 0
this.carts.forEach(item=>{
let products = item.productList
products.forEach(pros=>{
if(pros.isChecked){
this.allPrice += pros.price*pros.count
}
})
})
},
_totalCount(){//同上
this.allCount = 0
this.carts.forEach(item=>{
this.allCount += item.checkedCount
})
}
👆选择全部商店的商品,已经计算总价和总数量的函数
watch:{//深度监听所有数据,每次改变重新计算总价和总数
carts:{
deep:true,
handler(val,oldval){
this._totalPeice()
this._totalCount()
}
}
}
👆使用watch方法并将deep属性设置为true,对carts的数据深度watcher,改变时重新统计总价,总数量
- 大量运用的三元运算,只要看懂,就不觉得复杂了
- 通过函数调用函数,最底层的函数来实现状态的改变,逻辑最为清晰
- 在实际调用接口中,可能没有
checked
这个状态值,使用vue.set
来对数据设置状态值 - 只是对购物车实现的demo,没有做添加,删除等功能,后期完善
- 主要逻辑来自于羽叶千寻,加上一点自己的优化
网友评论