微信小程序之渲染商品列表

1.组件封装radio勾选状态

打开vue组件的源代码,为商品的左侧图片区域添加 radio 组件:

javascript 复制代码
<!-- 商品左侧图片区域 -->
<view class="goods-item-left">
		<radio checked color="#c0c0c0"></radio>
		<image:src="goods.goods_small_loge||defaultPic" class="goods_pic"></image>
</view>

当用户点击radio 组件,希望修改当前商品的勾选状态,此时可以为 my-goods 组件绑定 @radio-change 事件,从而获取当前商品Id

javascript 复制代码
<block v-for="(goods,i) in cart":key="i">
	<my-goods :goods="goods" :show-radio="true" @radio-change="radioChange"></my-goods>
</block>

声明如下 mutations 方法,用来修改对应商品的勾选状态:

javascript 复制代码
updateGoodsState(state,goods) {
		const findResult=state.cart.find(x => x.goods_id===goods_id)
		
		if(findResult) {
			//更新对应商品的勾选状态
			findResult.goods_state=goods.goods_state
			//持久化储存到本地
			this .commit('m_cart/saveToStorage')
		}
	}

为 my-goods组件封装 num-change 事件

当用户修改NumberBox 的值以后,可以将最新的商品数量更新到购物车中

javascript 复制代码
<!-- 商品列表区域 -->
<block v-for="(goods, i) in cart" :key="i">
  <my-goods :goods="goods" :show-radio="true" :show-num="true" @radio-change="radioChangeHandler" @num-change="numberChangeHandler">
</block>

在vue组件中,为组件绑定@change事件处理函数:

javascript 复制代码
<view class="goods-info-box">
	  <!-- 价格 -->
	  <view class="goods-price">${{goods.goods_price | tofixed}}</view>
	  <!-- 数量-->
	  <uni-number-box :min="1" :value="goods.goods_count"@change="numChangeHandler">
      </uni-number-box>
</view>  

2.信息储存

创建用户相关的vuex模块,命名为 users.js

javascript 复制代码
export default {
		//开启命名空间
		namespaced: true,
		
		// state 数据
		state: () => ({
			// 收货地址
			address: {},
		}),
		
		//方法
		mutations: {
			// 更新收货地址
			updataAddress(state,address) {
				state.address=address
			},
		},
		// 数据包装器
		getters: {},
}

改造组件中的代码,使用vuex提供的address计算属性代替data中定义的本地address对象

javascript 复制代码
// 按需导入 mapState 和 mapMutations 这两个辅助函数
import { mapState,mapMutations } from'vuex'

export default {
	data() {
		return {
			//address:{}
		}
	},
	methods: {
		...mapMutations('m_user',['updateAdderss']),
		//选择收货地址
		async chooseAddress() {
			const [err,succ]=await uni.chooseAddress().catch((err) => err)
			
			//用户成功选择了收货地址
			if(err === null&&succ.errMsg === 'chooseAddress:ok') {
				//this.address=succ
				this.updateAddress(succ)
			}
		},
	},
	computed: {
		...mapState('m_user',['address']),
		//收货详细地址的计算属性
		addstr() {
			if(!this.address.provinceName)return''
			return this.address.provinceName+this.address.cityName+this.address.counyryName+this.address.detailInfa
		},
	},
}

将Store中的address持久化存储到本地

javascript 复制代码
export default {
		//开启命名空间
		namespaced: true,
		
		// state 数据
		state: () => ({
			// 收货地址
			address: JSON.parse(uni.getStorageSy('address')|| '{}'),
		}),
		
		//方法
		mutations: {
			// 更新收货地址
			updataAddress(state,address) {
				state.address=address
        //通过this.commit()方法,调用m_user模块下的 saveAddressToStorage 方法将 address持久化储存到本地
          this.commit('m_user/saveAddressToStorage')
			},
        saveAddressToStorage(state) {
          uni.setStorageSync('address',JSON.stringify(state.address))
          },
		},
		// 数据包装器
		getters: {},
}

将addstr抽离为getters

目的:为了提高代码的复用性,可以把收货的详细地址抽离为getters,方便在多个页面和组件之间实现复用

javascript 复制代码
// 数据包装器
		getters: {
			//收货详细地址的计算属性
			addstr(state) {
				if(!state.address.provinceName)return''
				
				//拼接 省,市,区的字符串并返回给用户
				return this.address.provinceName+this.address.cityName+this.address.counyryName+this.address.detailInfa
			}
		},

通过 mapGetters 辅助函数函数,将m_user 模块中 addstr 映射到当前组件中使用:

javascript 复制代码
import { mapState,mapMutations,mapGetters } from'vuex'

export default {
  computed: {
    ...mapState('m_user',['address']),
    //将m_user 模块中的 addstr 映射到当前组件中使用
    ...mapGetters('m_user',['addatr']),
  },
}

解决地址授权失败的问题

javascript 复制代码
async reAuth() {
		//提示用户对地址进行授权
		const [err2,confirmResult]=await uni.showModal({
			content:'检测到您没打开地址权限,是否去设置打开?'
			confirmText:"确认",
			cancelText:"取消"
		})
		//如果弹框异常,则直接退出
		if(err2)return
		
		//若点击"取消"按钮
		if(confirmResult.cancl)return uni.$showMsg('您取消了地址授权!')
		
		//若点击"确认"按钮
		if (confirmResult.confirm)return uni.openSetting({
			success: (settingResult)=>{
				if(settingResult.authSetting['scope.address'])return uni.$showMsg('授权成功')
				if(!settingResult.authSetting['scope.address'])return uni.$showMsg('您取消了地址授权')
			}
		})
	}

3.结算组件

动态渲染已勾选商品的总数量

javascript 复制代码
checkedCount(state) {
		//先使用 filter 方法,从购物车中过滤器已勾选的商品
		//再使用 reduce 方法,将已勾选的商品总数量进行累加
		return state.cart.filter(x => x.goods_state).reduce((total,item)=> total+=item.goods_count,0)
	}

通过mapGetters 辅助函数,将需要的getters映射到当前组件中使用:

javascript 复制代码
import { mapGetters } from'vuex'

export default {
		computed: {
			...mapGetters('m_cart',['checkedCount'])
		},
		data() {
			return {
				
			}
		}
	}

动态渲染全选按钮的选中状态

使用 mapGetters 辅助函数,将商品的总数量映射到当前组件中使用,并定义一个叫做 isFullCheck 的计算属性:

javascript 复制代码
import { mapGetters } from'vuex'
	
	export default {
		computed: {
			...mapGetters('m_cart',['checkedCount','total']),
			// 是否全选
			isFullCheck() {
				return this.total === this.checkedCount
			},
		},
		data() {
			return {
				
			};
		}
	}

定义一个getters,用来统计已勾选商品总价格:

javascript 复制代码
//已勾选商品总价
	checkedGoodsAmount(state) {
		//先使用 filter 方法,从购物车中过滤器已勾选的商品
		//再使用 reduce 方法,将已勾选的商品数量 * 单价之后,进行累加
		//最后调用 toFixed(2)方法,保留两位小数
		return state.cart.filter(x=> x.goods_state)
						 .reduce((total,item)=>total+=item.goods_count*item.goods_count * item.goods_price,0)
						 .toFixed(2)
	}	
相关推荐
海兰18 小时前
【文字三国志:第六篇】天命重构,UI组件设计细节
人工智能·ui·语言模型·小程序
草根站起来21 小时前
微信小程序request net:ERR_CERT_DATE_INVALID
微信小程序·小程序
小北的AI科技分享1 天前
广州小程序平台推荐:2026年本地商家数字化选型深度测评
小程序·广州小程序平台
MageGojo1 天前
10 种主题随机诗词:一个 API 解决小程序的诗词内容源
python·小程序·古诗词·api 接入
青山科技分享1 天前
2026北京小程序平台推荐——本地商家数字化选型全维度解析
小程序·小程序平台推荐
肖有米XTKF86462 天前
肖有米团队开发:青蓝山泉送水模式系统
小程序·团队开发·零售·csdn开发云
double_eggm2 天前
微信小程序7
微信小程序·小程序
程序鉴定师2 天前
上海小程序开发的坚实保障与行业优势解析
大数据·小程序
double_eggm2 天前
微信小程序8
微信小程序·小程序