效果图:
商品相关数据大致结构:
shopcard: [{
num: 1,
price: '1999',
title: '商品名商品名商品名商品商品名',
desc: '商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述商品描述',
thumb: '图片地址'
},
......
]
另外,暂时还没有与后端关联,购物车内商品数据暂时写死在vuex内,移除商品功能也临时使用splice功能
首先,页面搭建:
<!-- 购物车列表 -->
<van-checkbox-group v-model="checkedGroup" ref="checkboxGroup">
<van-card
:price="item.price"
:desc="item.desc"
v-for="(item,index) in shopcard" :key="index"
>
<template slot="title"> <!-- 自定义标题部分,主要是为了添加删除商品按钮 -->
<span>{
{item.title}}</span>
<span style="float:right;" @click="removeShop(item)"><van-icon name="delete" /></span>
</template>
<template slot="thumb"> <!-- 自定义左侧部分,为了添加左侧checkbox -->
<van-checkbox :name="item.title" checked-color="#b90505" icon-size="12px"></van-checkbox>
<van-image :src="item.thumb"></van-image>
</template>
<template slot="bottom"> <!-- 自定义底部,为了实现商品数量功能 -->
<div class="num">
<van-button size="small" @click="minusnum(item)" :disabled="item.num <=1">-</van-button> <!-- 数量小于1时禁用按钮 -->
{
{item.num}}
<van-button size="small" @click="addnum(item)">+</van-button>
</div>
</template>
</van-card>
</van-checkbox-group>
<!-- 统计 -->
<div class="count">
<van-row style="text-align:center">
<van-col span="6"> <!-- 全选CheckBox部分 -->
<van-checkbox @click="checkAll" v-model="isAllChecked" checked-color="#b90505" icon-size="12px">全选</van-checkbox>
</van-col>
<van-col span="12" style="font-size:14px"> <!-- 总价格部分 -->
总计:<span style="font-size:16px;font-weight:700">{
{'¥'+allcount}}</span>
</van-col>
<van-col span="6"> <!-- 结算按钮 -->
<van-button round color="#b90505">结算</van-button>
</van-col>
</van-row>
</div>
data数据中主要有两个:checkedGroup:[]和shopcard:this.$store.state.shopcard,前者绑定在van-checkbox-group上,表示选中的商品卡片,后者为购物车商品总列表。
全选功能实现:
//computed中,判断全选状态
isAllChecked(){
if(this.checkedGroup.length === this.shopcard.length && this.shopcard.length !==0){ //选中数与商品总数相等并且购物车内存在商品
return true //表示全选状态
}else{
return false //表示未全选
}
},
//methods中,点击全选按钮时
checkAll(){
if(this.checkedGroup.length !== 0){ //有商品卡片选中
if(this.checkedGroup.length === this.shopcard.length){ //总商品数与选中商品卡片数相等,说明此时已全选
this.$refs.checkboxGroup.toggleAll(false); //令所有选中的反选,即全不选
}else{ //商品卡片数部分选中
this.$refs.checkboxGroup.toggleAll(true); //令所有商品全部选中
}
}else{ //没有商品卡片选中,直接全选
this.$refs.checkboxGroup.toggleAll(true);
}
},
商品数量的增减:(数量控制在标签内:disabled="item.num <=1")
addnum(item){
this.shopcard.find(element => {
return element.title === item.title
}).num = parseInt(item.num) + 1
},
minusnum(item){
this.shopcard.find(element => {
return element.title === item.title
}).num = parseInt(item.num) - 1
},
总价计算:
//computed中
allcount(){
let sumup = 0
for(let i=0;i<this.shopcard.length;i++){
if(this.checkedGroup.find(item => { //判断是否选中商品,未选中不计算在内
return item === this.shopcard[i].title
})){
sumup += this.shopcard[i].num*this.shopcard[i].price
}else{
continue
}
}
return sumup
},
删除商品:
//methods中,点击删除商品图标按钮时
removeShop(item){
for(let i=0;i<this.shopcard.length;i++){
if(item.title === this.shopcard[i].title){
let index = this.checkedGroup.indexOf(item.title)
this.shopcard.splice(i,1) //移除商品
if(index === -1){
return
}
this.checkedGroup.splice(index,1) //移除checkedGroup中刚刚删除的商品,不然不会即时刷新
}
}
}