1、制作头部

		<!-- #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、点击按钮完成和编辑进行切换

 
给按钮传一个点击事件进行判断即可
		data() {
			return {
				isEdit:true,
			}
		},			tab(){
				this.isEdit = !this.isEdit
			}3、编辑底部合计部分随着编辑一同显示

 
		<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、在完成页面中显示底部样式

<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 | 仅出现在 App 平台下的代码 | 
| #ifndef H5 | 除了 H5 平台,其它平台均存在的代码 | 
| #ifdef H5 || MP-WEIXIN | 在 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中引入

在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'])
		}

 

 
全部选中:
 
 
 
计算总价:

 按钮出现不可选中状态
 按钮出现不可选中状态

 
 
单选按钮

 
 
全选

全不选

删除

 

异步接收方法













