写了个简易的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>