uniapp实现购物车功能

本文介绍了使用uniapp实现购物车功能的详细步骤,包括页面结构搭建、样式设置、模拟数据创建、商品选中状态处理、数量增减功能以及结算金额计算。通过实例代码展示了全选、单选、数量加减及总价计算的逻辑实现。

uniapp实现购物车功能

周六我看见一个有个公司招聘需要试岗3天,并使用uniapp完成购物车,直播间,地图,首页四个功能方能通过,于是乎,我趁手上没事就打算自己写一遍,虽然我的项目没用到,但是多掌握点总没错。今天就来第一个——购物车
在这里插入图片描述

因为没写接口,上面的数据我都是使用的模拟数据搭建而成,主要实现的是它件数的增加减少与支付总价格的逻辑关系,还有左边的全选和全不选。
首先第一步,我们把页面先搭建出来

<template>
	<view>
	//购物车没商品出现的页面
		<view class="empty" v-if="show==false">
			<image src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic.51yuansu.com%2Fpic3%2Fcover%2F01%2F82%2F40%2F596fa6dc00bb4_610.jpg&refer=http%3A%2F%2Fpic.51yuansu.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1633499781&t=d37222e32213957ddbdd01d62e071309" mode="widthFix" style="width: 400rpx;"></image>
		<view class="empty-text">空空如也的购物</view>
		<view class="empty-button" @click="goshopping">去选购</view>
		</view>
		//购物车加购商品的东西
		<view v-if="show==true">
		//通过循环商品呈现出每个商品
			<view class="goods-detail" v-for="(item,index) in goods" :key="index">
				<view class="detail-left">
					<view class="goods-left">
					//商品的选择框
						<checkbox-group @change="selected(item)">
							<label>
								<checkbox  class="selected" color="#555555" :checked="checked"/>
							</label>
						</checkbox-group>
						  <image :src="item.goodsImage" mode="widthFix" style="width: 150rpx;"></image>
					</view>
					<view class="size">
					    <text style="font-size: 25rpx;">尺码:{
  
  {item.size}}</text>
					    <text class="goods-price">¥{
  
  {item.price}}/件</text>
					</view>
				</view>
				<view class="detail-right">
					<text class="subtract" @click="reduce(item)">-</text>
					<text class="num">{
  
  {item.num}}</text>
					<text @click="add(item)" class="add">+</text>
				</view>
			</view>
		</view>
		//全选总计
		<view class="end">
			<view class="end-left">
				<checkbox-group @change="selectgoods()">
					<label>
						<checkbox  :checked="allchecked" />全选
					</label>
				</checkbox-group>
				<view>
					总计:<text style="color: #f00;font-weight: bold;">¥ {
  
  {totalPrice}}</text>
				</view>
				</view>
				<view class="end-right">
				    结算({
  
  {totalNum}})
				</view>
			
			
		</view>
	</view>
</template>

这是我们页面的结构
其中最开始有一个v-if,大家都知道这是用于条件判断的

<view class="empty" v-if="show==false">
			<image src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic.51yuansu.com%2Fpic3%2Fcover%2F01%2F82%2F40%2F596fa6dc00bb4_610.jpg&refer=http%3A%2F%2Fpic.51yuansu.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1633499781&t=d37222e32213957ddbdd01d62e071309" mode="widthFix" style="width: 400rpx;"></image>
		<view class="empty-text">空空如也的购物</view>
		<view class="empty-button" @click="goshopping">去选购</view>
		</view>

这一块就是当我们的购物车是空的时候,页面应该呈现的样子。我也给大家截图出来了

### UniApp 实现购物车功能的解决方案 以下是基于 UniApp 平台实现购物车功能的一个完整方案,涵盖了界面设计、逻辑交互以及核心代码示例。 #### 1. **购物车界面布局** 通过 `view` 和 `scroll-view` 组件构建基础结构,支持商品展示、数量调整、单选/全选等功能。同时引入动态绑定数据来渲染商品列表[^1]。 ```html <template> <view class="cart-container"> <!-- 店铺分组 --> <block v-for="(shop, shopIndex) in cartData" :key="shopIndex"> <view class="shop-header"> <checkbox-group @change="handleShopSelect($event, shop)"> <label><checkbox value="" />{{ shop.name }}</label> </checkbox-group> </view> <!-- 商品列表 --> <view class="product-list"> <block v-for="(item, index) in shop.products" :key="index"> <view class="product-item"> <checkbox-group @change="handleProductSelect($event, item)"> <label><checkbox value="" /></label> </checkbox-group> <image :src="item.image"></image> <text>{{ item.title }}</text> <view class="price">{{ item.price }}元</view> <view class="quantity-controls"> <button @click="decreaseQuantity(item)">-</button> <input type="number" v-model="item.quantity"/> <button @click="increaseQuantity(item)">+</button> </view> </view> </block> </view> </block> <!-- 总价栏 --> <view class="total-bar"> <checkbox-group @change="selectAllProducts"> <label>全选:<checkbox value="" /></label> </checkbox-group> 合计:¥{{ totalPrice }} <button @click="checkout">结算({{ selectedCount }})</button> </view> </view> </template> ``` --- #### 2. **核心逻辑实现** ##### 数据管理与状态同步 使用 Vuex 来集中存储和管理购物车中的商品数据,确保组件间的数据一致性[^2]。 ```javascript // store.js export default { state: { ShoppingCart: [] }, mutations: { ADD_TO_CART(state, product) { const existingItem = state.ShoppingCart.find(p => p.id === product.id); if (existingItem) { existingItem.quantity++; } else { state.ShoppingCart.push({ ...product, quantity: 1 }); } }, REMOVE_FROM_CART(state, productId) { state.ShoppingCart = state.ShoppingCart.filter(p => p.id !== productId); }, UPDATE_QUANTITY(state, payload) { const item = state.ShoppingCart.find(p => p.id === payload.id); if (item) { item.quantity = payload.quantity; } } }, actions: { addToCart({ commit }, product) { commit('ADD_TO_CART', product); }, removeFromCart({ commit }, productId) { commit('REMOVE_FROM_CART', productId); }, updateQuantity({ commit }, payload) { commit('UPDATE_QUANTITY', payload); } }, getters: { totalItems: state => state.ShoppingCart.reduce((sum, item) => sum + item.quantity, 0), totalPrice: state => state.ShoppingCart.reduce((sum, item) => sum + item.price * item.quantity, 0) } }; ``` ##### 功能方法定义 在 Vue 方法中封装增删改查的核心业务逻辑: ```javascript <script> import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'; export default { data() { return { cartData: [] // 初始化店铺及商品数据 }; }, computed: { ...mapState(['ShoppingCart']), ...mapGetters(['totalItems', 'totalPrice']), selectedCount() { return this.cartData.flatMap(shop => shop.products).filter(product => product.selected).length; } }, methods: { ...mapMutations(['ADD_TO_CART', 'REMOVE_FROM_CART', 'UPDATE_QUANTITY']), ...mapActions(['addToCart', 'removeFromCart', 'updateQuantity']), handleShopSelect(event, shop) { const isChecked = event.detail.value.length > 0; shop.products.forEach(product => (product.selected = isChecked)); }, handleProductSelect(event, product) { product.selected = !product.selected; }, increaseQuantity(product) { this.updateQuantity({ id: product.id, quantity: product.quantity + 1 }); }, decreaseQuantity(product) { if (product.quantity > 1) { this.updateQuantity({ id: product.id, quantity: product.quantity - 1 }); } }, selectAllProducts(event) { const isChecked = event.detail.value.length > 0; this.cartData.forEach(shop => shop.products.forEach(product => (product.selected = isChecked)) ); }, checkout() { console.log('即将结算的商品:', this.cartData.flatMap(shop => shop.products).filter(product => product.selected)); } } }; </script> ``` --- #### 3. **优化体验:左滑删除功能** 为了提升用户体验,在移动端加入左滑删除的功能。此部分依赖于触摸事件监听器[^3]。 ```html <!-- 左滑删除模板 --> <view class="swipe-delete" @touchstart="onTouchStart" @touchmove="onTouchMove" @touchend="onTouchEnd"> <view class="content">{{ item.title }}</view> <view class="delete-btn" @tap.stop="onDelete">删除</view> </view> ``` ```javascript data() { return { startX: 0, moveX: 0, isSwiping: false }; }, methods: { onTouchStart(e) { this.startX = e.touches[0].pageX; this.isSwiping = true; }, onTouchMove(e) { if (!this.isSwiping) return; this.moveX = e.touches[0].pageX - this.startX; if (Math.abs(this.moveX) > 50) { this.showDeleteBtn = this.moveX < 0 ? true : false; } }, onTouchEnd() { this.isSwiping = false; setTimeout(() => (this.showDeleteBtn = false), 300); // 自动隐藏按钮 }, onDelete() { this.removeFromCart(this.item.id); } } ``` --- #### 4. **总结** 以上展示了如何在 UniApp实现一个完整的购物车功能模块,包括但不限于商品展示、数量控制、价格计算、全选/单选切换以及左滑删除等特性。这些功能均可以通过灵活组合 HTML 结构、Vue 生命周期钩子函数以及 Vuex 状态管理模式得以高效实现
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值