uniapp购物车多商家商品实现(删除-添加-结算-总价计算-总数合计-单选全选-快速清理-)

 附带源码(无插件)

<template>
	<view>
		<view class="cartBox" style="padding-bottom: 90rpx;">
			<!-- 头部选项卡 -->
			<view class="card-header">
				<view class="card-jzheader">
					<text>购物车</text>
					<text>({{totalNum}})</text>
				</view>
				<view @click="tab" class="card-zheader">
					<view v-if="isEdit">管理</view>
					<view v-else>完成</view>
				</view>
			</view>
			<!-- 商品商家列表 -->
			<view class="cartShop" v-for="(items,index) in list" :key="index">
				<!-- 商家列表 -->
				<view class="cartName cartPad">
					<view class="cart-xxkbk">
						<radio :checked="items.shopSelected==1" color="#ff2d52" style="transform:scale(0.8)"
							@click="shopselect(items)" />
					</view>
					<view class="cartName-box" @tap="goShop(items)">
						<image :src="items.logo" class="cartName-img"></image>
						<view style="max-width:400rpx;overflow:hidden; white-space: nowrap;text-overflow:ellipsis;">
							{{items.marketname}}
						</view>
					</view>
					<image src="../../static/sptupian/right.png" class="cartName-go" @tap="goShop(items)"></image>
				</view>
				<!-- 商品列表 -->
				<view v-for="(item,k) in items.cart" :key="k" class="cartCont" @click="goodSelect(items,item)">
					<view class="cartDetail">
						<view class="cart-xxksbbk">
							<radio :checked="item.goodsSelected==1" color="#ff2d52" style="transform:scale(0.8)" />
						</view>
						<view class="cartDetail-img">
							<image :src="item.imgurl" class="cartDetail-imgs"></image>
						</view>
						<view class="cartDetail-title">
							<view class="cartDetail-txt">
								<view class="cartDetail-bk">
									<view class="cartDetail-mz">
										{{item.goodsname}}
									</view>
								</view>
							</view>
							<view class="cartDetail-lab">
								规格:{{item.skuvalue}}
							</view>
							<view class="cartNum">
								<view class="cartNum-txt">
									<view style="margin-bottom: 15rpx;">
										<text style="font-size: 25rpx;">{{item.price}}</text>
										<text style="font-size: 25rpx;">{{item.tonzheng}}</text>
									</view>
								</view>
								<view class="add-sub-con">
									<text class="link" :class="item.num==1? 'jj':'aj'"
										@click.stop="cutAction(item)">-</text>
									<text class="input1 num input">{{item.num}}</text>
									<text class="link" :class="item.num*1<item.kucun*1? 'aj':'jj'"
										@click.stop="addAction(item)">+</text>
								</view>
							</view>
						</view>
						<view class="cartDetail-tb">
							<image :src="item.imgul" class="cartDetail-imgss"></image>
							<view class="db">
								<view class="pick">
									<uni-icons type="heart" color="gray" size="20"></uni-icons>
									<text>收藏</text>
								</view>
								<view class="pick">
									<uni-icons type="trash" color="gray" size="20"></uni-icons>
									<text @click="allDeldg">删除</text>
								</view>
							</view>
						</view>
					</view>
				</view>
			</view>
			<!-- 底部选项卡 -->
			<view v-if="isEdit" class="cartTotal">
				<view class="cartTotal-title">
					<view class="cartTotal-title">
						<radio :checked="list.allSelected==1" color="#ff2d52" style="transform:scale(0.8)"
							@click="selectAllAction" />
						<view class="cart-choose" @click="selectAllAction">
							全选
						</view>
					</view>
					<view class="cart-num">
						<view class="cart-numTxt">
							合计:
							<text style="font-size: 20rpx; color:orange">{{totalPrice.toFixed(2)}}工业通证</text>
							<text style="font-size: 20rpx; color:orange">{{totalPrice.toFixed(2)}}农业通证</text>
						</view>
						<view class="cart-wenzi">
							不含运费
						</view>
					</view>
				</view>
				<view class="cartTotal-btn" @tap="submitAction">
					去结算
				</view>
			</view>
			<view v-else class="cartTotal2">
				<view class="cartTotal-title2">
					<view class="cartTotal-title3">
						<radio :checked="list.allSelected==1" color="#ff2d52" style="transform:scale(0.8)"
							@click="selectAllAction" />
						<view class="cart-choose" @click="selectAllAction">
							全选
						</view>
					</view>
					<view class="cart-ksql" @click="allDel">
						快速清理
					</view>
					<view class="cart-shanchu" @click="deleteItem">
						删除
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				selectArr: [],
				isEdit: true,
				img: this.imgBaseUrl,
				totalPrice: 439.00,
				list: [{
						marketid: "0131",
						allSelected: 1,
						marketname: "前海万联旗舰店",
						logo: "../../static/sptupian/shop.png",
						shopSelected: 1,
						subTotal: 39.00,
						cart: [{
								cartid: 415,
								goodsid: 508,
								skuid: 879,
								skuvalue: "XL 白色",
								num: 1,
								goodsname: "软妹毛绒绒外套女秋冬季可爱小熊耳朵冬日系连帽毛毛上衣兔毛皮草",
								marketid: "0131",
								imgurl: "../../static/sptupian/1.png",
								imgul: "../../static/sptupian/more.png",
								price: 138,
								tonzheng: "工业通证",
								kucun: 300,
								goodsSelected: 1,
							},
							{
								cartid: 416,
								goodsid: 508,
								skuid: 879,
								skuvalue: "XL 白色",
								num: 1,
								goodsname: "软妹毛绒绒外套女秋冬季可爱小熊耳朵冬日系连帽毛毛上衣兔毛皮草",
								marketid: "0131",
								imgurl: "../../static/sptupian/1.png",
								imgul: "../../static/sptupian/more.png",
								price: 108,
								tonzheng: "农业通证",
								kucun: 300,
								goodsSelected: 1,
							},
						]
					},
					{
						marketid: "0131",
						allSelected: 1,
						marketname: "前海万联旗舰店",
						logo: "../../static/sptupian/shop.png",
						shopSelected: 1,
						subTotal: 39.00,
						cart: [{
								cartid: 417,
								goodsid: 508,
								skuid: 879,
								skuvalue: "XL 白色",
								num: 1,
								goodsname: "软妹毛绒绒外套女秋冬季可爱小熊耳朵冬日系连帽毛毛上衣兔毛皮草",
								marketid: "0131",
								imgurl: "../../static/sptupian/1.png",
								imgul: "../../static/sptupian/more.png",
								price: 138,
								tonzheng: "工业通证",
								kucun: 300,
								goodsSelected: 1,
							},
							{
								cartid: 418,
								goodsid: 508,
								skuid: 879,
								skuvalue: "XL 白色",
								num: 1,
								goodsname: "软妹毛绒绒外套女秋冬季可爱小熊耳朵冬日系连帽毛毛上衣兔毛皮草",
								marketid: "0131",
								imgurl: "../../static/sptupian/1.png",
								imgul: "../../static/sptupian/more.png",
								price: 108,
								tonzheng: "农业通证",
								kucun: 300,
								goodsSelected: 1,
							},
						]
					},
				],
				checkData: [],
				cart: [],
			}
		},
		computed: {
			//计算选中商品的总价
			totalPrice() {
				let prices = 0;
				let tzprices = 0;
				if (!!this.list) {
					this.list.map(shopItem => {
						shopItem.cart.map(goodItem => {
							goodItem.goodsSelected == 1 ? prices += goodItem.price * goodItem.num :
								prices += 0;
						})
					})
				}
				return prices;
			},
			//购物车商品总数
			totalNum() {
				let totalp = 0;
				if (!!this.list) {
					this.list.map(shopItem => {
						shopItem.cart.map(item => {
							return item.num ? totalp += item.num : totalp += 0
						})
					})
				}
				return totalp.toFixed(0)
			},
		},
		methods: {
			//删除单个数组
			allDeldg() {
				this.list.map(shopItem => {
					shopItem.cart.map((item, index) => {
						if (item.cartid == this.checkData.cartid) {
							this.cart.splice(index, 1)
							return true
						}
					})
				})
			},
			//清空所有数据
			allDel() {
				this.list = [];
			},
			//编辑切换
			tab() {
				this.isEdit = !this.isEdit
			},
			shopselect(shopItem, goodItem) {
				//遍历此店铺中商品 并全部选择
				if (shopItem.shopSelected == 0) {
					shopItem.shopSelected = 1
					shopItem.cart.map(goodItem => {
						goodItem.goodsSelected = 1;
						this.cart.push(goodItem)
					});
				} else {
					shopItem.shopSelected = 0
					shopItem.cart.map(goodItem => {
						goodItem.goodsSelected = 0;
					});
					this.cart = this.cart.filter((item) => {
						return item.marketid != shopItem.cart[0].marketid
					})
				}
				this.changeSelectAllBtn();
			},
			// 选择商品
			goodSelect(shopItem, goodItem) {
				this.checkData.push(goodItem)
				// 如果商品没选中 则不选中店铺
				if (goodItem.goodsSelected == 0) {
					goodItem.goodsSelected = 1
					shopItem.shopSelected = true;
					//店铺中商品都满足条件 则返回true
					const shopS = shopItem.cart.every(goodItem => {
						return goodItem.goodsSelected == 1;
					});

					//商品都选中  则店铺选中
					if (shopS) {
						shopItem.shopSelected = 1;
					}
					this.cart.push(goodItem)
				} else {
					goodItem.goodsSelected = 0
					shopItem.shopSelected = 0;
					this.cart.map((el, index) => {
						if (el.cartid == goodItem.cartid) {
							this.cart.splice(index, 1)
						}
					})
				}
				//监听全选按钮状态
				this.changeSelectAllBtn();
			},
			// 选择全部
			selectAllAction() {
				//遍历数据数组--遍历店铺  修改选择
				if (this.list.allSelected == 0) {
					this.list.allSelected = 1
					this.cart = []
					this.list.map(shopItem => {
						shopItem.shopSelected = 1;
						shopItem.cart.map((goodItem, index) => {
							this.cart.push(goodItem)
							goodItem.goodsSelected = 1;
						});
					});
				} else {
					//反选
					this.list.allSelected = 0
					this.list.map(shopItem => {
						shopItem.shopSelected = 0;
						shopItem.cart.map(goodItem => {
							this.cart = []
							goodItem.goodsSelected = 0;
						});
					});
				}
			},
			/* 选择店铺或者商品 监听全选按钮状态 */
			changeSelectAllBtn() {
				const selectAll = this.list.every(shopItem => {
					return shopItem.shopSelected == 1;
				});
				if (selectAll) {
					this.list.allSelected = 1
				} else {
					this.list.allSelected = 0
				}
			},
			// 增加数量
			addAction(goodItem) {
				if (goodItem.num >= parseInt(goodItem.kucun)) {
					uni.showToast({
						title: '不能再多了~',
						icon: 'none'
					});
					return true
				}
				goodItem.num++;
			},
			// 减少数量
			cutAction(goodItem) {
				if (goodItem.num > 1) {
					goodItem.num--;
				} else {
					uni.showToast({
						title: '不能再少了~',
						icon: 'none'
					});
				}
			},
			// 删除
			deleteItem() {
				console.log(this.checkData);
				this.list.forEach((item, index) => {
					if (item.cartid == this.checkData.cartid) {
						this.cart.splice(index, 1);
						return true;
					}
				})
			},
			// 结算
			submitAction() {
				let ALL = []
				this.cart.map(goodItem => {
					let cartarr = {}
					cartarr["cartid"] = goodItem.cartid
					cartarr["goodsid"] = goodItem.goodsid
					cartarr["num"] = goodItem.num
					cartarr["skuid"] = goodItem.skuid
					ALL.push(cartarr)
				});
			}
		}
	}
</script>

<style lang="scss" scoped>
	page {
		background-color: #F4F5F8;
	}

	.cartBox {
		background-color: #f3f3f3;
		padding-top: 20rpx;
	}

	.card-header {
		width: 750rpx;
		height: 44rpx;
		background-color: #f3f3f3;
		position: fixed;
		top: 0rpx;
		display: flex;
		z-index: 999;
	}

	.card-zheader {
		width: 80rpx;
		height: 44rpx;
		// margin-left: 12rpx;
	}

	.card-jzheader {
		display: flex;
		margin: auto;
		margin-left: 280rpx;
	}

	.cartShop {
		margin-top: 30rpx;
		box-shadow: 0 0 9rpx 3rpx #ccc;
		background-color: white;
		border-radius: 10rpx;
		width: 716rpx;
		margin-left: 16rpx;
		margin-right: 16rpx;
		margin-bottom: 20rpx;
		overflow: hidden;
	}

	.cartPad {
		margin: 0 26rpx;
	}

	.cartName {
		height: 100rpx;
		font-size: 29rpx;
		color: #333333;
		display: flex;
		align-items: center;
	}

	.cart-xxkbk {
		width: 50rpx;
		height: 100rpx;

		radio {
			margin-top: 30rpx;
		}
	}

	.cartName-box {
		width: 270rpx;
		height: 30rpx;
		display: flex;
		align-items: center;
	}

	.cartName-img {
		width: 30rpx;
		height: 30rpx;
		margin: 0 18rpx;
		border-radius: 50%;
	}

	.cartName-imgs {
		width: 113rpx;
		height: 35rpx;
		margin-left: 18rpx;
	}

	.cartName-go {
		margin-left: 8.5rpx;
		width: 16rpx;
		height: 27rpx;
	}

	.cartCont {
		position: relative;
		width: 716rpx;
		height: 230rpx;
	}

	.cartDetail {
		position: absolute;
		left: 25rpx;
		width: 700rpx;
		height: 230rpx;
		border-radius: 10rpx;
		display: flex;
		align-items: center;
		margin-top: 10rpx;
	}

	.cart-xxksbbk {
		width: 50rpx;
		height: 230rpx;

		radio {
			margin-top: 90rpx;
		}
	}

	.cartDetail-img {
		width: 180rpx;
		height: 200rpx;
		border-radius: 10rpx;
	}

	.cartDetail-imgs {
		border-radius: 10rpx;
		width: 180rpx;
		height: 200rpx;
	}

	.cartDetail-title {
		width: 420rpx;
		height: 200rpx;
		font-size: 29rpx;
		color: #333333;
		margin-left: 12rpx;
	}

	.cartDetail-txt {
		width: 420rpx;
		height: 60rpx;
		font-size: 12rpx;
		line-height: 1.2;
		overflow: hidden;
		text-overflow: ellipsis;
		display: -webkit-box;
		-webkit-box-orient: vertical;
		-webkit-line-clamp: 2;
	}

	.cartDetail-bk {
		width: 420rpx;
		height: 60rpx;
		display: flex;
	}

	.cartDetail-mz {
		width: 350rpx;
		height: 60rpx;
		font-size: 25rpx;
		line-height: 1.2;
		overflow: hidden;
		text-overflow: ellipsis;
		display: -webkit-box;
		-webkit-box-orient: vertical;
		-webkit-line-clamp: 2;
	}

	.cartDetail-tb {
		position: absolute;
		top: 20rpx;
		left: 620rpx;
		width: 50rpx;
		height: 30rpx;
	}

	.cartDetail-tb:hover {
		background-color: #f3f3f3;
	}

	.db {
		position: absolute;
		right: 0rpx;
		display: none;
		background-color: white;
		box-shadow: 0 0 9rpx 3rpx #ccc;
		text-align: center;
		width: 120rpx;
		height: 120rpx;
		color: gray;
	}

	.cartDetail-tb:hover .db {
		display: block;
	}

	.pick {
		width: auto;
		height: 35px;
	}

	.cartDetail-imgss {
		width: 50rpx;
		height: 50rpx;
	}

	.cartDetail-lab {
		width: 420rpx;
		height: 35rpx;
		margin-top: 20rpx;
		font-size: 20rpx;
		color: #ccc;
	}

	.cartNum {
		width: 420rpx;
		height: 30rpx;
		display: flex;
		margin-top: 30rpx;
		justify-content: space-between;
		align-items: center;
		padding-bottom: 26rpx;
	}

	.cartNum-txt {
		margin-top: 50rpx;
		font-size: 20rpx;
		color: #ff2d52;
	}

	.cartTotal {
		width: 750rpx;
		height: 91rpx;
		background-color: white;
		font-size: 28rpx;
		color: #333333;
		display: flex;
		align-items: center;
		padding-left: 27rpx;
		position: fixed;
		left: 0;
		bottom: 0;
		z-index: 10;
	}

	.cartTotal-title {
		width: 500rpx;
		height: 91rpx;
		display: flex;
		align-items: center;
	}

	.cart-choose {
		margin: 0 21rpx 0 14rpx;
	}

	.cart-num {
		font-size: 31rpx;
		color: #ff2d52;
		text-align: right;
		padding-right: 11rpx;
	}

	.cart-numTxt {
		width: 220rpx;
		font-size: 20rpx;
		color: black;
	}

	.cart-wenzi {
		font-size: 20rpx;
		color: black;
	}

	.cartTotal-btn {
		margin-left: 30rpx;
		width: 150rpx;
		height: 70rpx;
		border-radius: 80rpx;
		font-size: 31rpx;
		color: white;
		border: 1rpx solid orangered;
		background-color: orangered;
		line-height: 75rpx;
		text-align: center;
	}

	.add-sub-con {
		border: 1rpx solid white;
		border-radius: 30rpx;
		margin-top: 35rpx;
	}

	.add-sub-con .link {
		float: left;
		width: 30rpx;
		height: 30rpx;
		border-radius: 50%;
		line-height: 32rpx;
		text-align: center;
		font-size: 32rpx;
		color: #666;
		border: #e5e5e5 solid 1px;
		background-color: #F8F8F8;
	}

	.add-sub-con .link.aj {
		color: gray;
		border: #e5e5e5 solid 1px;
		background: #fff;
	}

	.add-sub-con .link.jj {
		color: gray;
		border: #e5e5e5 solid 1px;
		background-color: #fff;
	}

	.add-sub-con .input {
		float: left;
		width: 50rpx;
		display: block;
	}

	.add-sub-con .input {
		width: 50rpx;
		height: 30rpx;
		line-height: 30rpx;
		box-sizing: border-box;
		text-align: center;
		font-size: 20rpx;
		-webkit-border-radius: 0;
		border: 1px solid transparent;
		border-left: none;
		border-right: none;
	}

	.cartTotal2 {
		width: 750rpx;
		height: 91rpx;
		background-color: white;
		font-size: 28rpx;
		color: #333333;
		display: flex;
		align-items: center;
		padding-left: 27rpx;
		position: fixed;
		left: 0;
		bottom: 0;
		z-index: 10;
	}

	.cartTotal-title2 {
		width: 700rpx;
		height: 91rpx;
		display: flex;
		align-items: center;
	}

	.cartTotal-title3 {
		width: 300rpx;
		height: 91rpx;
		display: flex;
		align-items: center;
	}

	.cart-ydgz {
		margin-left: 30rpx;
		width: 180rpx;
		height: 50rpx;
		border-radius: 80rpx;
		font-size: 25rpx;
		color: orange;
		border: 1rpx solid orange;
		background-color: transparent;
		line-height: 55rpx;
		text-align: center;
	}

	.cart-ksql {
		margin-left: 30rpx;
		width: 180rpx;
		height: 50rpx;
		border-radius: 80rpx;
		font-size: 25rpx;
		color: orange;
		border: 1rpx solid orange;
		background-color: transparent;
		line-height: 55rpx;
		text-align: center;
	}

	.cart-shanchu {
		margin-left: 30rpx;
		width: 180rpx;
		height: 50rpx;
		border-radius: 80rpx;
		font-size: 25rpx;
		color: white;
		border: 1rpx solid orangered;
		background-color: orangered;
		line-height: 55rpx;
		text-align: center;
	}

	.remove {
		margin-left: -5%;
		width: 80px;
		height: 100%;
		background-color: red;
		color: #FFFFFF;
		position: absolute;
		top: 0;
		right: -80px;
		display: flex;
		justify-content: center;
		align-items: center;
		font-size: 16px;
	}
</style>

多余数据自己删除,数据自己更改

新人博主多多支持


版权声明:本文为weixin_69658614原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。