写了个简易的uniapp购物车价格计算,单选,全选,数量加减,计算对应价格,帮助理解购物车的计算逻辑。
前提准备
使用到了一个uniapp数量加减的组件,请自行下载导入:
https://uniapp.dcloud.net.cn/component/uniui/uni-number-box.html

选中和未选中图片素材:


效果预览

template代码
<template>
<view class="content">
<view class="carBox">
<view class="caritem" v-for="(item,index) in list" :key="index">
<view class="delBox">
<image @click="selectFun(item)" :src="item.isSelect?'../../static/seled.png':'../../static/sel.png'"
mode="widthFix"></image>
</view>
<view class="infos">
<image :src="item.image" mode=""></image>
<view class="nameBox">
<view class="title">
{{item.name}}
</view>
<view class="desc">
{{item.desc}}
</view>
</view>
</view>
<view class="numBox">
<text>¥{{item.price}}</text>
<view class="nums">
<uni-number-box :value='item.num' min="1" @change="changeValue($event,item)" />
</view>
</view>
</view>
</view>
<view class="bottomBox">
<view class="b-left" @click="allselectFun">
<image :src="isAllSel?'../../static/seled.png':'../../static/sel.png'" mode="widthFix"></image>
<text>全选</text>
</view>
<view class="b-right">
<view class="all">
<text>共计:</text>
<text style="font-size: 34rpx; color: red;font-weight: 600;">¥{{totalPrice}}</text>
</view>
<button class="btn" type="default" @click="submitFun">结算</button>
</view>
</view>
</view>
</template> css代码
<style scoped>
.content {
background-color: #f5f5f5;
min-height: 100vh;
}
.caritem {
height: 160rpx;
background-color: #ffffff;
display: flex;
justify-content: flex-start;
align-items: center;
padding: 0 10rpx;
box-sizing: border-box;
margin-bottom: 15rpx;
}
.caritem .delBox>image {
width: 44rpx;
border-radius: 50%;
margin-right: 20rpx;
}
.delBox {
text-align: center;
}
.caritem .infos {
width: 70%;
display: flex;
justify-content: flex-start;
align-items: center;
}
.nameBox {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
}
.caritem .infos image {
width: 160rpx;
height: 150rpx;
margin-right: 20rpx;
}
.numBox {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.nums {
margin-top: 15rpx;
}
.nameBox .title {
font-weight: 600;
}
.nameBox .desc {
font-size: 24rpx;
color: #555555;
margin-top: 15rpx;
}
.bottomBox {
width: 100%;
background-color: #fff;
position: fixed;
bottom: 0;
left: 0;
padding: 20rpx;
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
}
.bottomBox .b-left {
display: flex;
justify-content: flex-start;
align-items: center;
}
.bottomBox .b-left image {
width: 40rpx;
border-radius: 50%;
margin-right: 10rpx;
}
.b-right {
display: flex;
}
.all {
margin-right: 50rpx;
}
.btn {
width: 200rpx;
height: 55rpx;
line-height: 55rpx;
text-align: center;
font-size: 28rpx;
background-color: #ff0000;
color: #fff;
}
</style> JS代码
<script>
export default {
data() {
return {
numberValue: 0,
vModelValue: 3,
// 购物车数据 必须按照这个格式
list: [{
id: 1,
name: '华为手机',
desc: '华为手机的描述',
image: 'https://img0.baidu.com/it/u=1006495301,1288022891&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800',
price: '10',
isSelect: true,
num: 1,
},
{
id: 2,
name: '笔记本电脑',
desc: '笔记本电脑的描述',
image: 'https://img2.baidu.com/it/u=73285818,881590808&fm=253&fmt=auto&app=138&f=JPEG?w=653&h=500',
price: '10',
isSelect: true,
num: 1,
},
{
id: 3,
name: '蓝牙耳机',
desc: '蓝牙耳机的描述',
image: 'https://img0.baidu.com/it/u=3898938150,1268246085&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
price: '10',
isSelect: true,
num: 1,
}
],
// 所有选中的商品列表
allshopList: [],
totalPrice: '', // 总价
isAllSel: false, // 是否全选
}
},
onLoad() {
// 先判断当前
this.getAllshops()
},
methods: {
// 选中商品
selectFun(item) {
console.log(item, "当商品新");
item.isSelect = !item.isSelect
// 获取当前选中商品列表
this.getAllshops()
},
// 获取所有的已选中的购物车商品及获取总价 以及判断是否全选
getAllshops() {
// 获取所有的已选中的购物车商品
this.allshopList = this.list.filter(v => {
return v.isSelect == true
})
console.log(this.allshopList, "已选中的购物车列表");
this.totalPrice = this.allshopList.reduce((total, item) => total + item.price * item.num, 0)
console.log(this.totalPrice, '算出总价');
// 每次点击选中的时候 都会调用此方法 都判断商品是否全部选中 这一步在selectFun方法中起作用
// 遍历所有商品 返回v.isSelect == false 即未选中的商品
let aa = this.list.filter(v => {
return v.isSelect == false
})
console.log(aa.length, "当前未选中的商品的数量");
// 如果得到的数组长度<=0 说明没有未选中的 那就时全选中了
// 此时就点亮全选按钮
if (aa.length <= 0) {
this.isAllSel = true
} else {
this.isAllSel = false
}
},
// 点击全选
allselectFun() {
this.isAllSel = !this.isAllSel
console.log(this.isAllSel, "全选状态");
// 如果this.isAllSel为真 则循环所有购物车数据吧isSelect全部改为true
if (this.isAllSel) {
this.list.forEach(v => {
v.isSelect = true
})
// 每次点击都调用计算价格方法
this.getAllshops()
} else {
this.list.forEach(v => {
v.isSelect = false
})
// 每次点击都调用计算价格方法
this.getAllshops()
}
},
// 点击结算按钮
submitFun() {
// 获取当前选中的商品 +方法计算总价
this.getAllshops()
},
change(value) {
this.numberValue = value
},
// 点击加减
changeValue(value, item) {
console.log('返回数值:', value, item);
// 修改当前点击的商品num 用于计算价格
item.num = value
// 再调用所有选中的商品 算出总价
this.getAllshops()
},
blur(e) {
console.log('blur:', e);
},
focus(e) {
console.log('focus:', e);
}
}
}
</script>








