uni-app实现商城多商家购物车功能(超详细, 附带源码)

我们先来看一下效果

有什么不懂可以直接下方留言

先来看代码

<template>
	<view class="cart">
		<!-- 购物车为空 S -->
		<view v-if="cartList.length === 0" class="empty">
			<image class="icongouwuche" src="../../static/icon_gouwuche.png" mode="widthFix"></image>
			<view v-if="hasLogin" class="empty-tips">
				空空如也
				<navigator class="navigator" :class="'text-' + themeColor.name" v-if="hasLogin" url="../classify/classify-index/index"
				 open-type="switchTab">随便逛逛</navigator>
			</view>
			<view v-else class="empty-tips">
				空空如也
				<view class="navigator" :class="'text-' + themeColor.name">
					登录/注册 >
				</view>
			</view>
		</view>
		<!-- 购物车为空 E -->
		<!-- 购物车列表 S -->
		<view class="goods-list" v-else>
			<view class="btn-clear">
				<view class="" :class="'text-' + themeColor.name">
					共0件宝贝
				</view>
				<view class="" @click="chooseSwitchover">
					{{adminShow? '完成': '编辑'}}
				</view>
			</view>
			<view class="yh-cart-row">
				<!-- 商品列表 S -->
				<block v-for="(item, index) in cartList" :key="index">
					<view class="carrier">
						<view class="shop">
							<view class="left">
								<image v-if="item.isShop" class="select" :src="selectPitchOn" mode="widthFix" @click="chooseShopSelect(index)"></image>
								<image v-if="!item.isShop" class="select" :src="selectDefault" mode="widthFix" @click="chooseShopSelect(index)"></image>
								<view class="shop-name">
									<image class="icon-shop" :src="shopImage" mode="widthFix"></image>
									<view class="name">
										{{item.shop_name}}
									</view>
								</view>
							</view>
							<image class="right" :src="rightImage" mode="widthFix"></image>
						</view>
						<view class="goods" v-for="(gItem, gIndex) in item.goods" :key="gIndex" v-if="gItem.goods_sold_out == 1">
							<view class="left">
								<image class="select" :src="gItem.selected ? selectPitchOn:selectDefault" mode="widthFix" @click="chooseGoodsSelect(index, gIndex)"></image>
							</view>
							<view class="right">
								<image class="goods-image" :src="gItem.goods_cover || errirImage"></image>
								<view class="goods-info">
									<view class="goods-name">
										{{gItem.goods_name}}
									</view>
									<view class="specification" @click="specificationSelection(index, gIndex)">
										<view class="specification-name">
											{{gItem.goods_specification != ''? gItem.goods_specification: ''}}
										</view>
										<block v-if="gItem.goods_specification != ''">
											<image class="specification-image" v-if="isSelection" :src="upImage" mode="widthFix"></image>
											<image class="specification-image" v-if="!isSelection" :src="downImage" mode="widthFix"></image>
										</block>
									</view>
									<view class="goods-price">
										<view class="price">
											<block v-if="gItem.goods_price != ''">
												<text class="price-symbol">¥</text>
												<text class="price-marked">{{gItem.goods_price}}</text>
											</block>
										</view>
										<view class="amount">
											<view class="num-minus" @click="chooseMinus(index, gIndex)">
												-
											</view>
											<view class="input-price">
												{{gItem.goods_num}}
											</view>
											<view class="num-add" @click="chooseAddNum(index, gIndex)">
												+
											</view>
										</view>
									</view>
								</view>
							</view>
						</view>
					</view>
				</block>
				<!-- 商品列表 E -->
			</view>
			<view class="yh-cart-row">
				<!-- 失效商品列表 S -->

				<view class="carrier">
					<view class="carrier-title" v-if="goodsLoseEfficacy.length != 0">
						<text class="goods-lose-efficacy-num">
							失效宝贝1件
						</text>
						<text class="goods-lose-efficacy-operation" @click="chooseLoseEfficacyGoodsEmpty">
							清空失效宝贝
						</text>
					</view>
					<view class="goods" v-for="(gItem, gIndex) in goodsLoseEfficacy" :key="gIndex" v-if="gItem.goods_sold_out == 0">
						<view class="left">
							<!-- <image class="select" :src="selectDefault" mode="widthFix"></image> -->
						</view>
						<view class="right">
							<image class="goods-image" :src="gItem.goods_cover || errirImage"></image>
							<view class="goods-info-s">
								<text class="goods-names">
									{{gItem.goods_name}}
								</text>
								<view class="specification" @click="specificationSelection">

								</view>
								<view class="goods-price">
									<view class="goods-cause">
										{{gItem.cause}}
									</view>
									<view class="goods-similarity">
										找相似
									</view>
								</view>
							</view>
						</view>
						<image class="goods-lose-efficacy-identifying" :src="loseEfficacyImage" mode="widthFix"></image>
					</view>
				</view>
				<!-- 失效商品列表 E -->
			</view>
		</view>
		<!-- 购物车列表 E -->
		<!-- 购物车结算 S -->
		<view class="goods-settle-accounts">
			<view class="left">
				<image v-if="isCheckAll" class="select" :src="selectPitchOn" mode="widthFix" @click="chooseCheckAll"></image>
				<image v-if="!isCheckAll" class="select" :src="selectDefault" mode="widthFix" @click="chooseCheckAll"></image>
				全选
			</view>
			<view class="right">
				<block v-if="!adminShow">
					<view class="goods-price-total">
						<text>合计: </text>
						<text>¥ {{total}}</text>
					</view>
					<view class="goods-count-btn">
						结算
					</view>
				</block>
				<block v-if="adminShow">
					<view class="goods-enshrine" @click="chooseGoodsEnshrine">
						移至收藏夹
					</view>
					<view class="goods-delete" @click="chooseGoodsDelete">
						删除
					</view>
				</block>
			</view>
		</view>
		<!-- 购物车结算 E -->
	</view>
</template>

<script>
	export default {
	
		data() {
			return {
				errirImage: this.$mAssetsPath.errorImage,
				rightImage: this.$mAssetsPath.right, // 右箭头图标
				shopImage: this.$mAssetsPath.shop, // 店铺图标
				selectDefault: this.$mAssetsPath.iconDefault, // 默认图标 
				selectPitchOn: this.$mAssetsPath.iconPitchOn, // 选中图标
				upImage: this.$mAssetsPath.iconUp, // 上
				downImage: this.$mAssetsPath.iconDown, // 下
				loseEfficacyImage: this.$mAssetsPath.loseEfficacy, // 失效
				cartList: [{
					shop_name: "惠多多自营",
					isShop: false,
					goods: [ // 购物车数据列表
						{
							goods_name: "小乳酸菌牛奶酸奶饮料整箱饮品早餐酸乳益生菌",
							goods_cover: "",
							goods_price: "520.00",
							goods_num: 1,
							goods_specification: "大小;尺寸",
							goods_sold_out: 1,
							cause: "库存不足",
							selected: false,
						},
						{
							goods_name: "小乳酸菌牛奶酸奶饮料整箱饮品早餐酸乳益生菌",
							goods_cover: "",
							goods_price: "520.00",
							goods_num: 1,
							goods_specification: "大小;尺寸",
							goods_sold_out: 1,
							cause: "库存不足",
							selected: false,
							specification: []
						}
					]
				},{
					shop_name: "惠多多自营",
					isShop: false,
					goods: [ // 购物车数据列表
						{
							goods_name: "小乳酸菌牛奶酸奶饮料整箱饮品早餐酸乳益生菌",
							goods_cover: "",
							goods_price: "520.00",
							goods_num: 1,
							goods_specification: "大小;尺寸",
							goods_sold_out: 1,
							cause: "库存不足",
							selected: false,
						},
						{
							goods_name: "小乳酸菌牛奶酸奶饮料整箱饮品早餐酸乳益生菌",
							goods_cover: "",
							goods_price: "520.00",
							goods_num: 1,
							goods_specification: "大小;尺寸",
							goods_sold_out: 1,
							cause: "库存不足",
							selected: false,
							specification: []
						}
					]
				}],
				goodsLoseEfficacy: [],
				total: 0, // 选中商品总价
				hasLogin: null,
				// 控制滑动效果
				adminShow: false, // 编辑选择默认false
				isStop: false, // 店铺下所有商品全选/取消全选默认false
				isSelection: false, // 规格选择默认false
				isCheckAll: false, // 购物车全选/反选默认false
			}
		},
		methods: {
			// 编辑按钮切换
			chooseSwitchover() {
				this.adminShow = !this.adminShow
			},
			// 选择规格
			specificationSelection(index, gindex) {
				let cartList = this.cartList;
				// console.log(cartList[index].goods[gindex])
				this.isSelection = !this.isSelection
			},
			// 增加数量
			chooseAddNum(index, gindex) {
				let cartList = this.cartList; // 购物车商品列表
				let goods_num = cartList[index].goods[gindex].goods_num; // 获取当前数量
				goods_num = goods_num + 1; // 每点击一次加1
				cartList[index].goods[gindex].goods_num = goods_num; // 数量
				this.totalPrice()
			},
			// 减少数量
			chooseMinus(index, gindex) {
				let cartList = this.cartList; // 购物车商品列表
				let goods_num = cartList[index].goods[gindex].goods_num; // 获取当前数量
				if (goods_num <= 1) {
					return
				}
				goods_num = goods_num - 1; // 每点击一次加1
				cartList[index].goods[gindex].goods_num = goods_num;
				this.totalPrice()
			},
			// 选中商品删除
			chooseGoodsDelete() {
				uni.showModal({
					content: "确认将这" + 1 + "个宝贝删除?",
					cancelText: "我再想想",
					cancelColor: "#999999",
					confirmText: "删除",
					confirmColor: "#fa436a",
					success(res) {
						if (res.confirm) {
							console.log("删除")
						} else if (res.cancel) {
							console.log("我再想想")
						}
					},
				})
			},
			// 选中商品移至收藏夹
			chooseGoodsEnshrine() {
				console.log("收藏")
			},
			// 清空失效商品
			chooseLoseEfficacyGoodsEmpty() {
				uni.showModal({
					content: "确认清空失效宝贝吗?",
					cancelText: "我再想想",
					cancelColor: "#999999",
					confirmText: "清空",
					confirmColor: "#fa436a",
					success(res) {
						if (res.confirm) {
							console.log("清空")
						} else if (res.cancel) {
							console.log("我再想想")
						}
					},
				})
			},
			// 计算总价
			totalPrice() {
				let cartList = this.cartList;
				let total = 0;
				let goods_num = 0;
				for (let i = 0; i < cartList.length; i++) {
					for (let j = 0; j < cartList[i].goods.length; j++) {
						if (cartList[i].goods[j].selected) {
							total += cartList[i].goods[j].goods_price * cartList[i].goods[j].goods_num;
							goods_num += cartList[i].goods[j].goods_num;
						}
					}
				}
				this.total = total;
			},
			// 店铺选中反选
			chooseShopSelect(index) {
				let cartList = this.cartList;
				cartList[index].isShop = !cartList[index].isShop;
				for (let i = 0; i < cartList[index].goods.length; i++) {
					cartList[index].goods[i].selected = cartList[index].isShop
				}
				this.checkAllCondition()
				this.totalPrice()
			},
			// 商品选中反选
			chooseGoodsSelect(index, gindex) {
				let cartList = this.cartList;
				let count = 0;
				let goodsList = cartList[index].goods; // 当前店铺下商品列表
				let goods = goodsList[gindex]; // 当前商品数组

				if (goods.selected) {
					cartList[index].goods[gindex].selected = false; // 改变当前商品状态
					cartList[index].isShop = false; // 改变店铺状态
				} else {
					cartList[index].goods[gindex].selected = true;
					// 当店铺选中商品数量与店铺总数相等时, 改变店铺状态
					let shopGoodsNum = cartList[index].goods.length;			// 店铺总个数
					let goodsArray = cartList[index].goods;
					let selectedNum = 0;
					for(var i in goodsArray) {
						if(goodsArray[i].selected) {
							selectedNum++
						}
					}
					if(selectedNum == goodsArray.length) {
						cartList[index].isShop = true
					} else {
						cartList[index].isShop = false
					}
				}
				this.checkAllCondition()
				this.totalPrice()
			},
			// 全选条件 店铺全选  反之 
			checkAllCondition() {
				let isCheckAll = this.isCheckAll;
				let cartList = this.cartList;					// 购物车列表数据
				let isCheckAllNum = 0;
				for (let i = 0; i < cartList.length; i++) {
					if(cartList[i].isShop == true) {
						isCheckAllNum++
					}
				}
				if(isCheckAllNum == cartList.length) {
					this.isCheckAll = true;
				} else {
					this.isCheckAll = false;
				}
				this.totalPrice()
			},
			// 点击全选
			chooseCheckAll() {
				let cartList = this.cartList;
				let isCheckAll = this.isCheckAll;
				if(isCheckAll) {
					this.isCheckAll = false
				} else {
					this.isCheckAll = true
				}
				for(let i=0; i<cartList.length; i++) {
					cartList[i].isShop = this.isCheckAll;
					for(let j=0; j<cartList[i].goods.length; j++) {
						cartList[i].goods[j].selected = this.isCheckAll
					}
				}
				this.totalPrice()
			}
		}
	}
</script>

<style lang="scss">
	.rightText {
		font-size: $font-sm;
		padding-top: 3px;
	}

	.empty {
		position: fixed;
		left: 0;
		top: 0;
		width: 100%;
		height: 100vh;
		padding-bottom: 100upx;
		display: flex;
		justify-content: center;
		flex-direction: column;
		align-items: center;
		background-color: #FFFFFFF;

		.icongouwuche {
			width: 190upx;
		}

		.empty-tips {
			display: flex;
			font-size: $font-sm + 2upx;
			color: $font-color-disabled;

			.navigator {
				margin-left: 16upx;
			}
		}
	}

	.goods-list {
		.btn-clear {
			display: flex;
			justify-content: space-between;
			margin: 0 30upx 20upx;
		}

		.yh-cart-row:last-child {
			margin: 0 30upx 120upx;
		}

		.yh-cart-row {
			background-color: #FFFFFF;
			border-radius: $spacing-base;
			margin: 0 30upx 30upx;

			.carrier:last-child {
				border-bottom: none;
			}

			.carrier {
				border-bottom: 1upx dashed #EEEEEE;

				.shop {
					display: flex;
					align-items: center;
					padding: 30upx 30upx;

					.left {
						display: flex;
						align-items: center;

						.select {
							width: 40upx;
							margin-right: $spacing-base;
						}

						.shop-name {
							display: flex;
							align-items: center;

							.icon-shop {
								width: 42upx;
								margin-right: $spacing-sm;
							}

							.name {
								font-size: $font-lg;
								font-weight: 600;
							}
						}
					}

					.right {
						width: 30upx;
						margin-left: $spacing-sm;
					}
				}

				.goods {
					display: flex;
					align-items: center;
					padding: 0 30upx 40upx;
					position: relative;

					.goods-lose-efficacy-identifying {
						width: 100upx;
						height: 100upx;
						position: absolute;
						z-index: 99;
						right: 0upx;
						margin-top: -75upx;
					}

					.left {
						.select {
							width: 40upx;
							margin-right: $spacing-base;
						}
					}

					.right {
						display: flex;
						z-index: 2;

						.goods-image {
							width: 220upx;
							height: 220upx;
							margin-right: 20upx;
						}

						.goods-info {
							width: 340upx;
							padding-top: 10upx;

							.goods-name {
								font-size: $font-th;
							}

							.specification {
								display: flex;
								align-items: center;
								margin-top: 10upx;

								.specification-name {
									font-size: $font-sm;
									color: $font-color-9;
								}

								.specification-image {
									width: 25upx;
									margin-left: $spacing-sm;
								}
							}

							.goods-price {
								display: flex;
								justify-content: space-between;
								margin-top: 20upx;

								.price {
									color: $base-color;

									.price-symbol {
										font-size: $font-sm;
									}

									.price-marked {
										font-size: $font-lg;
									}
								}

								.amount {
									display: flex;
									align-items: center;
									height: 40upx;
									border: 1upx solid $font-color-9;

									.num-minus,
									.num-add {
										width: 40upx;
										text-align: center;
									}

									.num-minus {
										height: 40upx;
										border-right: 1upx solid $font-color-9;
									}

									.num-add {
										height: 40upx;
										border-left: 1upx solid $font-color-9;
									}

									.input-price {
										width: 60upx;
										text-align: center;
									}
								}
							}
						}

						.goods-info-s {
							// 失效商品样式
							width: 400upx;
							padding-top: 10upx;

							.goods-names {
								font-size: $font-th;
								color: $font-color-9;
							}

							.specification {
								display: flex;
								align-items: center;
								margin-top: 10upx;

								.specification-name {
									font-size: $font-sm;
									color: $font-color-9;
								}

								.specification-image {
									width: 25upx;
									margin-left: $spacing-sm;
								}
							}

							.goods-price {
								display: flex;
								justify-content: space-between;
								margin-top: 20upx;
								align-items: center;

								.goods-cause {
									// 商品失效原因
									font-size: $font-sm;
									margin-top: 45upx;
								}

								.goods-similarity {
									font-size: $font-sm;
									color: $base-color;
									padding: 5upx 10upx;
									border: 1upx solid $base-color;
									margin-top: 45upx;
									border-radius: 20upx;
								}
							}
						}
					}
				}

				.carrier-title {
					display: flex;
					justify-content: space-between;
					padding: 20upx 30upx 30upx;

					.goods-lose-efficacy-num {
						font-size: $font-base;
						font-weight: 600;
					}

					.goods-lose-efficacy-operation {
						font-size: $font-sm;
						padding-top: 4upx;
						color: $base-color;
					}
				}
			}
		}
	}

	.goods-settle-accounts {
		height: 96upx;
		position: fixed;
		bottom: 50px;
		z-index: 99;
		width: 100%;
		background-color: #FFFFFF;
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 0 30upx;
		border-top: 1upx solid $border-color-whiteSmoke;

		.left {
			display: flex;
			align-items: center;

			.select {
				width: 40upx;
				margin-right: $spacing-sm;
			}
		}

		.right {
			display: flex;
			align-items: center;

			.goods-price-total {
				font-size: $font-lg;
			}

			.goods-price-total text:nth-child(2) {
				font-size: $font-base;
				padding-top: 4upx;
				margin-left: 8upx;
				color: $base-color;
			}

			.goods-count-btn {
				font-size: 32upx;
				width: 180upx;
				background-color: $base-color;
				color: $color-white;
				border-radius: 30upx;
				height: 66upx;
				text-align: center;
				line-height: 66upx;
				margin-left: 20upx;
			}

			.goods-enshrine {
				color: $base-color;
				padding: 5upx 20upx;
				border: 1upx solid $base-color;
				border-radius: 30upx;
				margin-right: 30upx;
			}

			.goods-delete {
				color: $font-colo-orange;
				padding: 5upx 20upx;
				border: 1upx solid $font-colo-orange;
				border-radius: 30upx;
			}
		}
	}
</style>

以上就是购物车所有代码,直接拿过去用, 别客气

如果对你有用,关注一下博主的小程序,登录一下给予支持,以后有什么开源好用的源码都会上传到小程序

 

  • 18
    点赞
  • 101
    收藏
    觉得还不错? 一键收藏
  • 34
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 34
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值