vue实现简单的购物车功能:
1、单选/全选选中状态的判断
2、只有选中后才会去计算总价
3、结算需要获取到已选中的数据
4、mescroll上拉刷新,下拉加载更多
该项目购物车数据没有做本地存储,加入购物车,数量的加减直接调用的接口,总价格是在前端进行计算
<template>
<div class="shop_cart">
<nav-bar :if_left_arrow="true" title="购物车" slot_right_text="删除" @clickSlotRight="clickSlotRight"></nav-bar>
<mescroll-vue ref="mescroll" :down="mescrollDown" :up="mescrollUp" @init="mescrollInit">
<!-- 购物车列表 -->
<div class="goods" v-if="dataShow">
<div class="title">
<!-- 全选按钮 -->
<van-checkbox v-model="if_all_checked" @click="all_checked">IEPC</van-checkbox>
</div>
<div class="item" v-for="(item,index) in goods" :key="index">
<!-- item.checked为$set方法新增的变量,用来判断单选 -->
<van-checkbox v-model="item.checked" @click="change_checked(index,item)"></van-checkbox>
<img class="goods-img" :src="item.goods_picture" alt="">
<div class="goods-details">
<h2 class="yihang">{{item.goods_name}}</h2>
<div class="img">
<img src="@images/mall/cart6.png" alt="">
<img src="@images/mall/cart5.png" alt="">
</div>
<b>¥{{item.price}}</b>
<div class="addnum">
<!-- ++ -->
<img src="@images/mall/cart7.png" @click="minus(index,item)">
<input :value="item.num" readonly onfocus="this.blur();">
<!-- -- -->
<img src="@images/mall/cart8.png" @click="plus(index,item)">
</div>
</div>
</div>
</div>
<!-- 暂无数据 -->
<no-data type="5" v-if="!dataShow"></no-data>
</mescroll-vue>
<div class="submit">
<div class="left">
<div class="text">
<span>合计:</span>
<div>
<b>IEPC {{total_IEPC}}</b>
<em>枚</em>
</div>
</div>
</div>
<button @click="submit">去结算</button>
</div>
</div>
</template>
<script>
export default {
//页面需要用到的数据
data() {
return {
if_all_checked: false, //全选判断
goods: [],//购物车列表
total_IEPC: '0.0000', //总价格默认0
dataShow: true,//是否有数据
mescroll: null,
mescrollDown: { auto: false, },
mescrollUp: { callback: this.upCallback, },
}
},
mounted() {
},
methods: {
//全选
all_checked() {
if (!this.if_all_checked) {
this.if_all_checked = true;//全选开启
this.goods.forEach((item, i) => {
item.checked = true;//每一项全部选中
this.total_IEPC = (Number(this.total_IEPC) + Number(item.goods_iepc_money) * item.num).toFixed(4); //计算总价:总价 = 总价 + 商品单价*商品数量
})
} else {
this.if_all_checked = false;//全选关闭
this.total_IEPC = '0.0000';//总价为0
this.goods.forEach((item, i) => {
item.checked = false;//每一项全部取消
})
}
},
//单选
change_checked(index,item) {
this.goods[index].checked = !this.goods[index].checked; //选中/取消
// 只有选中才会计算价格++,否则--
if(this.goods[index].checked){
this.total_IEPC = (Number(this.total_IEPC) + Number(item.goods_iepc_money) * item.num).toFixed(4); //计算总价:总价 = 总价 + 商品单价*商品数量
}else{
this.total_IEPC = (Number(this.total_IEPC) - Number(item.goods_iepc_money) * item.num).toFixed(4); //计算总价:总价 = 总价 - 商品单价*商品数量
}
let flag = true;// flag:判断是否全部选中
this.goods.forEach(item => {
//未全部选中
if (!item.checked) {
flag = false;
this.if_all_checked = false;
}
});
//全部选中
if (flag) {
this.if_all_checked = true;
}
},
//数量++
plus(index, item) {
this.axios.post('/api/cart/cartAdjustNum', {
goods_id: item.goods_id,
type: 2,
cid: item.cart_id,
}).then(res => {
if (res.status == 1) {
//判断必须选中才计算价格++,默认只增加数量
if(this.goods[index].checked){
this.total_IEPC = (Number(this.total_IEPC) + Number(item.goods_iepc_money)).toFixed(4); //计算总价:总价 = 总价 + 商品单价*商品数量
}
this.goods[index].num++;
}
})
},
//数量--
minus(index, item) {
if (item.num > 1) {
this.axios.post('/api/cart/cartAdjustNum', {
goods_id: item.goods_id,
type: 1,
cid: item.cart_id,
}).then(res => {
if (res.status == 1) {
//判断必须选中才计算价格--,默认只减少数量
if(this.goods[index].checked){
this.total_IEPC = (Number(this.total_IEPC) - Number(item.goods_iepc_money)).toFixed(4); //计算总价:总价 = 总价 - 商品单价*商品数量
}
this.goods[index].num--;
}
})
}
},
//删除
clickSlotRight() {
if(this.goods.length == 0){
this.$toast('没有可删除的数据');
}else{
//arr:已经选中项
let arr = this.goods.filter(item => {
return item.checked == true;
});
let caet_id_Arr=[];//已经选中项的id集合
arr.forEach(item=>{
caet_id_Arr.push(item.cart_id);
})
let data = caet_id_Arr.join(',');//需要删除的数据 : 24,25,26
this.$dialog.alert({
title: '您是否要删除已选中的商品',
showCancelButton:true,
confirmButtonText:'删除'
}).then(() => {
this.total_IEPC='0.0000';
this.axios.post('/api/cart/cartDel',{
cid:data,
}).then(res=>{
if(res.status == 1){
this.$toast('删除成功');
this.mescroll.triggerDownScroll(); // 重新加载列表
}
})
});
}
},
//去结算
submit() {
// arr:filter方法返回满足条件的新数组:已经选中需要结算的数据
let arr = this.goods.filter(item => {
return item.checked == true;
});
if( JSON.parse(localStorage.getItem('userInfo')).pay_status == 0 ){
this.$dialog.confirm({
title:'你还没有设置交易密码哦',
message: '设置交易密码才可以进行下一步',
confirmButtonText:'设置密码',
showCancelButton: true,
confirmButtonColor: '#139BFA',
}).then(() => {
this.$router.push('pay_pwd');
}).catch(() => {});
}else if(this.goods.length == 0){
this.$toast('没有可结算的商品')
} else{
this.$store.commit('set_goods_detail',arr);//结算数据存vuex,供下个页面使用
this.$router.push('shop_order?total_money='+this.total_IEPC);
}
},
//下拉加载,上拉刷新
mescrollInit(mescroll) {
this.mescroll = mescroll;
},
upCallback(page, mescroll) {
this.axios.post('/api/cart/cart_list', {
page: page.num,
}).then(res => {
if (res.status == 1) {
this.if_all_checked = false; //每次刷新全选关闭
this.total_IEPC = '0.0000'; //总价格价格为0
let arr = res.data.list;
arr.forEach(item => {
this.$set(item, "checked", false); //$set方法,给数组添加新属性,判断是否被选中,默认值false
})
if (page.num === 1) this.goods = [];
this.goods = this.goods.concat(arr);
this.$nextTick(() => {
mescroll.endSuccess(arr.length)
})
if (this.goods.length == 0) {
this.dataShow = false;
}
}
}).catch((e) => {
mescroll.endErr();
this.dataShow = false;
});
},
}
}
</script>