uniapp——商城购物车联动效果

1、制作头部

uniapp——商城购物车联动效果

		<!-- #ifdef MP -->
		<search-slot>
			<view class="left" slot="left">
			</view>
			<view class="center" slot="center">
				购物车
			</view>
			<view class="right" slot="right" A>
				<view v-if="isEdit">编辑</view>
				<view v-else>完成</view>
			</view>
		</search-slot>
		<!-- #endif -->

样式

  .left {
  	width: 100rpx;
  	align-items: center;
  	text-align: center;
  }
  
  .center {
  	flex: 1;
  	text-align: center;
  }
  
  .right {
  	width: 100rpx;
  	text-align: center;
	align-items: center;
  }

2、点击按钮完成和编辑进行切换

uniapp——商城购物车联动效果

 uniapp——商城购物车联动效果

给按钮传一个点击事件进行判断即可 

		data() {
			return {
				isEdit:true,
			}
		},
			tab(){
				this.isEdit = !this.isEdit
			}

 3、编辑底部合计部分随着编辑一同显示

uniapp——商城购物车联动效果

 uniapp——商城购物车联动效果

		<template v-if="isEdit">
			<view class="d-flex a-center position-fixed left-0 right-0 bottom-0 ju border-top border-light-secondary a-stretch"
			 style="height: 100rpx;z-index: 100;">
				<label class="radio d-flex a-center j-center flex-shrink" style="width: 120rpx;">
					<radio color="#FD6801" ></radio>
				</label>
				<view class="flex-1 d-flex a-center j-center font-md">
					合计 <p-price>{{totalPrice}}</p-price>
				</view>
				<view class="flex-1 d-flex a-center j-center main-bg-color text-white font-md" hover-class="main-bg-hover-color">
					结算
				</view>
			</view>
		</template>

微信小程序中的hover-class属性

微信小程序中,可以用 hover-class 属性来指定元素的点击态效果。但是在在使用中要注意,大部分组件是不支持该属性的。

目前支持 hover-class 属性的组件有三个:view、button、navigator。


4、在完成页面中显示底部样式

uniapp——商城购物车联动效果

<template v-else>
			<view class="d-flex a-center position-fixed left-0 right-0 bottom-0 ju border-top border-light-secondary a-stretch"
			 style="height: 100rpx;z-index: 100;">
				<label class="radio d-flex a-center j-center flex-shrink" style="width: 120rpx;" >
					<radio  color="#FD6801" ></radio>
				</label>
				<view class="flex-1 d-flex a-center j-center font-md main-bg-color text-white">
					移入收藏
				</view>
				<view 
				  class="flex-1 d-flex a-center j-center bg-danger text-white font-md" 
				  hover-class="main-bg-hover-color"
				 >
					删除
				</view>
			</view>
		</template>

条件编译

条件编译是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。

写法:以 #ifdef 或 #ifndef 加 %PLATFORM% 开头,以 #endif 结尾。

  • #ifdef:if defined 仅在某平台存在
  • #ifndef:if not defined 除了某平台均存在
  • %PLATFORM%:平台名称
条件编译写法 说明

#ifdef APP-PLUS
需条件编译的代码
#endif

仅出现在 App 平台下的代码

#ifndef H5
需条件编译的代码
#endif

除了 H5 平台,其它平台均存在的代码

#ifdef H5 || MP-WEIXIN
需条件编译的代码
#endif

在 H5 平台或微信小程序平台存在的代码(这里只有||,不可能出现&&,因为没有交集)

%PLATFORM% 可取值如下:

生效条件
VUE3 HBuilderX 3.2.0+ 详情
APP-PLUS App
APP-PLUS-NVUE或APP-NVUE App nvue
H5 H5
MP-WEIXIN 微信小程序
MP-ALIPAY 支付宝小程序
MP-BAIDU 百度小程序
MP-TOUTIAO 字节跳动小程序
MP-LARK 飞书小程序
MP-QQ QQ小程序
MP-KUAISHOU 快手小程序
MP-360 360小程序
MP 微信小程序/支付宝小程序/百度小程序/字节跳动小程序/飞书小程序/QQ小程序/360小程序
QUICKAPP-WEBVIEW 快应用通用(包含联盟、华为)
QUICKAPP-WEBVIEW-UNION 快应用联盟
QUICKAPP-WEBVIEW-HUAWEI 快应用华为

基本样式完成后接下来用vuex来写数据

uniapp中自带vuex所以无需再安装,直接调用即可

创建一个store文件夹里面存放index.js,代码如下:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import cart from './modules/cart.js'
let store = new Vuex.Store({
	modules:{
		cart
	}
})
export default store

在main.js中引入

uniapp——商城购物车联动效果

 

在store文件夹中再新建一个modules文件里面包裹一个cart.js

state中填入list列表

list: [ {
			checked: false,
			id: 11,
			title: "商品标题111",
			cover: "/static/images/demo/list/1.jpg",
			// 选中商品属性
			attrs: [{
					title: "颜色",
					selected: 0,
					list: [{
							name: '火焰红',
						},
						{
							name: '炭黑',
						},
						{
							name: '冰川兰',
						}
					]
				},
				{
					title: "容量",
					selected: 0,
					list: [{
							name: '64GB',
						},
						{
							name: '128GB',
						},
					]
				},
				{
					title: "套餐",
					selected: 0,
					list: [{
							name: '标配',
						},
						{
							name: '套餐一',
						},
						{
							name: '套餐二',
						}
					]
				},
			],
			pprice: 336,
			num: 1,
			minnum: 1,
			maxnum: 10, // 该商品最大商品数,跟库存有关
		},
		{
			checked: false,
			id: 12,
			title: "商品222",
			cover: "/static/images/demo/list/1.jpg",
			// 选中商品属性
			attrs: [{
					title: "颜色",
					selected: 0,
					list: [{
							name: '火焰红',
						},
						{
							name: '炭黑',
						},
						{
							name: '冰川兰',
						}
					]
				},
				{
					title: "容量",
					selected: 0,
					list: [{
							name: '64GB',
						},
						{
							name: '128GB',
						},
					]
				},
				{
					title: "套餐",
					selected: 0,
					list: [{
							name: '标配',
						},
						{
							name: '套餐一',
						},
						{
							name: '套餐二',
						}
					]
				},
			],
			pprice: 200,
			num: 1,
			minnum: 1,
			maxnum: 10, // 该商品最大商品数,跟库存有关
		},
		{
			checked: false,
			id: 13,
			title: "商品标题333",
			cover: "/static/images/demo/list/1.jpg",
			// 选中商品属性
			attrs: [{
					title: "颜色",
					selected: 0,
					list: [{
							name: '火焰红',
						},
						{
							name: '炭黑',
						},
						{
							name: '冰川兰',
						}
					]
				},
				{
					title: "容量",
					selected: 0,
					list: [{
							name: '64GB',
						},
						{
							name: '128GB',
						},
					]
				},
				{
					title: "套餐",
					selected: 0,
					list: [{
							name: '标配',
						},
						{
							name: '套餐一',
						},
						{
							name: '套餐二',
						}
					]
				},
			],
			pprice: 100,
			num: 2,
			minnum: 1,
			maxnum: 10, // 该商品最大商品数,跟库存有关
		} 
		],
		selectedAll:[]//储存选中数据

也可以单独这么写:

// 页面路径:store/index.js 
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex); //vue的插件机制

//Vuex.Store 构造器选项
const store = new Vuex.Store({
	state: {
		list: [{
				checked: false, //按钮状态
				id: 11, // id用来区分每个不同的按钮
				title: "商品标题111",
				cover: "/static/images/demo/list/1.jpg",
				// 选中商品属性
				attrs: [{
						title: "颜色",
						selected: 0, // 选中的第几个,默认从0开始
						list: [{
								name: '火焰红',
							},
							{
								name: '炭黑',
							},
							{
								name: '冰川兰',
							}
						]
					},
					{
						title: "容量",
						selected: 0,
						list: [{
								name: '64GB',
							},
							{
								name: '128GB',
							},
						]
					},
					{
						title: "套餐",
						selected: 0, //选中状态
						list: [{
								name: '标配',
							},
							{
								name: '套餐一',
							},
							{
								name: '套餐二',
							}
						]
					},
				],
				pprice: 336, //商品价格
				num: 1, // 初始值
				minnum: 1, // 按钮最大值
				maxnum: 10, // 该商品最大商品数,跟库存有关
			},
			{
				checked: false,
				id: 12,
				title: "商品222",
				cover: "/static/images/demo/list/1.jpg",
				// 选中商品属性
				attrs: [{
						title: "颜色",
						selected: 0,
						list: [{
								name: '火焰红',
							},
							{
								name: '炭黑',
							},
							{
								name: '冰川兰',
							}
						]
					},
					{
						title: "容量",
						selected: 0,
						list: [{
								name: '64GB',
							},
							{
								name: '128GB',
							},
						]
					},
					{
						title: "套餐",
						selected: 0,
						list: [{
								name: '标配',
							},
							{
								name: '套餐一',
							},
							{
								name: '套餐二',
							}
						]
					},
				],
				pprice: 200,
				num: 1,
				minnum: 1,
				maxnum: 10, // 该商品最大商品数,跟库存有关
			},
			{
				checked: false,
				id: 13,
				title: "商品标题333",
				cover: "/static/images/demo/list/1.jpg",
				// 选中商品属性
				attrs: [{
						title: "颜色",
						selected: 0,
						list: [{
								name: '火焰红',
							},
							{
								name: '炭黑',
							},
							{
								name: '冰川兰',
							}
						]
					},
					{
						title: "容量",
						selected: 0,
						list: [{
								name: '64GB',
							},
							{
								name: '128GB',
							},
						]
					},
					{
						title: "套餐",
						selected: 0,
						list: [{
								name: '标配',
							},
							{
								name: '套餐一',
							},
							{
								name: '套餐二',
							}
						]
					},
				],
				pprice: 100,
				num: 2,
				minnum: 1,
				maxnum: 5, // 该商品最大商品数,跟库存有关
			}
		],
		selectedAll: [] //储存选中数据

	},
	getters: {
		// 购物车为空时出现购物车图标
		disSelect(state) {
			return state.list.length === 0;
		},
		//全部选中
		checkedAll(state) {
			return state.list.length === state.selectedAll.length
		},
		//计算总价
		totalPrice(state) {
			let total = 0
			state.list.forEach(v => {
				/* if(state.selectedAll.indexOf(v.id)!=-1){
					total += v.pprice * v.num
				} */
				console.log(v.num);
				if (v.checked) {
					total += v.pprice * v.num
				}

			})
			return total
		},
		//合计按钮不可用状态
		disabled(state) {
			if (state.list.length === 0) {
				state.list.checked = false
				return true
			}

		}
	},
	mutations: {
		//单选按钮
		selectItem(state, index) {
			var id = state.list[index].id
			var i = state.selectedAll.indexOf(id)
			if (i > -1) {
				// 取消当前商品选中状态
				state.list[index].checked = false
				// 移除选中列表中的当前商品
				return state.selectedAll.splice(i, 1)
			}
			// 选中
			state.list[index].checked = true
			state.selectedAll.push(id)
			console.log(state.selectedAll);
		},

		//全选
		selectAll(state) {
			state.selectedAll = []
			state.list.map(v => {
				v.checked = true
				state.selectedAll.push(v.id)
			})
			/* state.selectedAll = state.list.map(v=>{
				    v.checked = true
					return v.id
			   }) */
		},
		//全不选
		noselectAll(state) {
			state.list.map(v => {
				v.checked = false
			})
			state.selectedAll = []
		},
		//删除商品
		delgoods(state) {
			uni.showModal({
				content: '您确定要删除吗',
				success: () => {
					// commit('delgoods')
					state.list = state.list.filter(v => {
						console.log(state.selectedAll.indexOf(v.id) === -1);
						return state.selectedAll.indexOf(v.id) === -1
					})
					state.selectedAll = [] //清空id
				},
				fail: (err) => {
					console.log(err);
				}
			})

		}
	},
	actions: {
		doselectAll({
			getters,
			commit
		}) {
			// 传getters中的状态,如果全选按钮是开启的那么就返回全不选,否则就在跳回全选
			getters.checkedAll ? commit('noselectAll') : commit('selectAll')
		},
	}

})
export default store

 数据基本完成,完成后再写个购物车为空的页面,如果没有获取到数据,那么购物车就显示空

<template v-if="disSelect">
			<view class="py-5 d-flex a-center j-center bg-white">
				<view class="iconfont icon-gouwuche text-light-muted" style="font-size: 50rpx;"></view>
				<text class="text-light-muted mx-2">购物车还是为空</text>
				<view class="px-2 py-1 border border-light-secondary rounded" hover-class="bg-light-secondary">
					去逛逛
				</view>
			</view>
		</template>

用计算属性引入

	getters: {
		// 购物车为空时出现暂无数据购物车图标
		disSelect(state){
			return state.list.length === 0
		}
	},

在页面用计算属性让其显示list列表 

		computed: {
			...mapState({
				list: (state) => state.list
			}),
			// 在这里引入
			...mapGetters(['disSelect'])

		}

uniapp——商城购物车联动效果


uniapp——商城购物车联动效果

 uniapp——商城购物车联动效果

uniapp——商城购物车联动效果

 uniapp——商城购物车联动效果


全部选中:

uniapp——商城购物车联动效果 uniapp——商城购物车联动效果

 uniapp——商城购物车联动效果

计算总价:

uniapp——商城购物车联动效果

uniapp——商城购物车联动效果 按钮出现不可选中状态

uniapp——商城购物车联动效果

 uniapp——商城购物车联动效果

 uniapp——商城购物车联动效果

 单选按钮

uniapp——商城购物车联动效果

 uniapp——商城购物车联动效果

 uniapp——商城购物车联动效果

 全选

uniapp——商城购物车联动效果

全不选

uniapp——商城购物车联动效果

删除

uniapp——商城购物车联动效果

 uniapp——商城购物车联动效果

uniapp——商城购物车联动效果

 异步接收方法

uniapp——商城购物车联动效果

uniapp——商城购物车联动效果

uniapp——商城购物车联动效果

上一篇:React 列表渲染


下一篇:React 条件判断