这是一个商城类项目基本必带的模块——购物车
此案例包含单选和全选的交互、数量的修改、总价的联动。
数据都是静态的数据,样式根据个人需要修改。
页面如下:
html代码:
<view class="cart">
<view class="content">
<view class="list" v-for="item in list" :key="item.id">
<view class="left">
<checkbox-group @change="checkboxChange(item, item.id)"><checkbox :value="item.id" :checked="item.isChecked" /></checkbox-group>
<image :src="item.img" class="img"></image>
</view>
<view class="center">
<view class="name">{
{ item.name }}</view>
<view class="size">规格:{
{ item.sku }}</view>
<view class="count">数量:x{
{ item.count }}</view>
</view>
<view class="right">
<view class="price">单价¥{
{ item.price }}元</view>
<view class="update-count">
<view class="reduce" @tap="editNum(item.id, -1)">-</view>
<view class="cart-count">{
{ item.count }}</view>
<view class="add" @tap="editNum(item.id, 1)">+</view>
</view>
</view>
</view>
</view>
<!-- 底部导航栏 -->
<view class="tabbar">
<view class="all">
<checkbox-group @change="checkboxChangeAll">
<checkbox :checked="isAllChecked" />
全选
</checkbox-group>
</view>
<view class="totalPrice">总价:¥{
{ totalPrice }}元</view>
<view class="submitOrder" @tap="submitOrder">付款</view>
</view>
</view>
js代码:
<script>
export default {
data() {
return {
list: [
{
id: '0',
name: '商品1',
price: 10,
count: 1,
sku: 'aa:bb',
img: '/static/logo.png'
},
{
id: '1',
name: '商品2',
price: 15,
count: 1,
sku: 'aa:cc',
img: '/static/logo.png'
},
{
id: '2',
name: '商品3',
price: 12,
count: 1,
sku: 'aa:dd',
img: '/static/logo.png'
},
{
id: '3',
name: '商品4',
price: 30,
count: 1,
sku: 'aa:ee',
img: '/static/logo.png'
}
], //列表数据
isAllChecked: false, //是否全选
totalPrice: 0
};
},
methods: {
// 每个商品点击
checkboxChange(e, id) {
this.list[id].isChecked = !this.list[id].isChecked
// 如果每个商品都被选中,全选勾选
var isCheck = true
this.list.forEach(item => {
if(!item.isChecked){
isCheck = false
}
})
this.isAllChecked = isCheck
// 修改选中商品重新计算价格
this.calcPrice()
},
// 修改数量
editNum(id, type) {
if (type == 1) {
this.list[id].count++;
} else {
if (this.list[id].count > 0) {
this.list[id].count--;
}
}
// 修改数量重新计算价格
this.calcPrice()
},
// 计算总价
calcPrice(){
var totalPrice = 0
for (let i = 0; i < this.list.length; i++) {
// 只计算选中的商品
if (this.list[i].isChecked) {
totalPrice += Number((Number(this.list[i].count) * Number(this.list[i].price) * 100 / 100).toFixed(2))
}
}
this.totalPrice = totalPrice
},
// 底部全选
checkboxChangeAll() {
// 更改全选状态
this.isAllChecked = !this.isAllChecked;
// 根据全选状态对每个商品进行更改
if (this.isAllChecked) {
this.list = this.list.map(item => {
item.isChecked = true;
return item;
});
} else {
this.list = this.list.map(item => {
item.isChecked = false;
return item;
});
}
this.calcPrice()
},
// 付款
submitOrder() {
var arr = [];
var name = ''
var id = ''
if (this.list.length > 0) {
for (let i = 0; i < this.list.length; i++) {
if (this.list[i].isChecked) {
arr.push(this.list[i])
name += this.list[i].name + ','
id += this.list[i].id + ','
}
}
}
if(arr.length == 0){
uni.showToast({
icon:'none',
title:'你得选商品啊',
duration:1500
})
} else {
console.log(arr, '选中商品的数组')
console.log(name.substring(0,name.length - 1), '选中商品的名字')
console.log(id.substring(0,id.length - 1), '选中商品的id')
}
}
},
mounted() {
// 一般情况,是否选中这个值后台是不返回的,所以需要在每一项加上是否选中的标志 根据具体情况选择加不加这个操作
this.list = this.list.map(item => {
item.isChecked = false;
return item;
});
}
};
</script>
css样式:
<style lang="scss" scoped>
.content {
width: 670rpx;
margin: 0 auto 180rpx;
}
// 居中显示
@mixin textCenter {
display: flex;
align-items: center;
justify-content: center;
}
.list {
width: 672rpx;
height: 208rpx;
background: #f9f9f9;
box-shadow: 0 8rpx 16rpx 0 rgba(83, 66, 49, 0.08);
border-radius: 24rpx;
margin-top: 32rpx;
display: flex;
justify-content: space-around;
align-items: center;
.left {
display: flex;
align-items: center;
.img {
width: 136rpx;
height: 136rpx;
margin-left: 10rpx;
border-radius: 8%;
}
}
.center {
width: 170rpx;
.name {
font-size: 26rpx;
color: #3e3e3e;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.size,
.count {
font-size: 22rpx;
color: #8d8d8d;
}
}
.right {
.price {
margin-top: 40rpx;
font-size: 26rpx;
margin-left: 40rpx;
}
// 加减数量
.update-count {
margin-top: 40rpx;
display: flex;
.reduce,
.add {
width: 40rpx;
height: 40rpx;
background: #f1ece7;
border-radius: 21.6rpx;
color: #979797;
@include textCenter;
font-size: 50rpx;
}
.cart-count {
width: 72rpx;
height: 40rpx;
line-height: 40rpx;
background: #f1ece7;
border-radius: 21.6rpx;
margin-left: 18rpx;
margin-right: 18rpx;
text-align: center;
}
}
}
}
// 底部导航
.tabbar {
width: 100%;
height: 176rpx;
background-color: #f3f3f3;
position: fixed;
bottom: 0;
display: flex;
align-items: center;
justify-content: space-around;
border-radius: 8% 8%;
.all {
font-size: 32rpx;
color: #3e3e3e;
letter-spacing: 2.29rpx;
display: flex;
}
.totalPrice {
font-size: 32rpx;
color: #3e3e3e;
letter-spacing: 2.29rpx;
color: red;
}
.submitOrder {
width: 208rpx;
height: 80rpx;
background: #354e44;
border-radius: 14rpx;
border-radius: 14rpx;
font-size: 36rpx;
color: #ffffff;
letter-spacing: 2.57rpx;
display: flex;
align-items: center;
justify-content: center;
}
}
</style>
当然还有优化空间,简单记录一下。