9.配置页面 - 商品列表区域
(1).渲染购物车商品列表的标题区域
cart.vue
<template> <view> <!-- 商品列表的标题区域 --> <view class="cart-title"> <!-- 左侧的图标 --> <uni-icons type="shop" size="18"></uni-icons> <!-- 描述文本 --> <text class="cart-title-text">购物车</text> </view> </view> </template>
<style lang="scss"> .cart-title { height: 40px; display: flex; align-items: center; padding-left: 5px; border-bottom: 1px solid #efefef; .cart-title-text { font-size: 14px; margin-left: 10px; } } </style>
(2).渲染商品列表区域的基本结构
1.通过 mapState 辅助函数,将 Store 中的 cart 数组映射到当前页面中使用:
<script> import badgeMix from '@/mixins/tabbar-badge.js' // 引入辅助函数 import { mapState } from "vuex" export default { mixins: [badgeMix], // 使用辅助函数 computed: { ...mapState('m_cart', ['cart']), }, data() { return { }; }, } </script>
2.在 UI 结构中,通过 v-for 指令循环渲染自定义的 my-goods 组件:
这里调用了子组件并传递参数
<!-- 循环渲染购物车中的数据 --> <block v-for="(item,index) in cart" :key="index"> <my-goods :item="item"></my-goods> </block>
(3).my-goods 组件封装 radio 勾选状态
1.打开 my-goods.vue 组件的源代码,为商品的左侧图片区域添加 radio 组件:
<!-- 商品左侧图片区域 --> <view class="goods-item-left"> <radio checked color="#C00000"></radio> <image :src="goods.goods_small_logo || defaultPic" class="goods-pic"></image> </view>
2.给类名为 goods-item-left 的 view 组件添加样式,实现 radio 组件和 image 组件的左右布局:
.goods-item-left { margin-right: 5px; display: flex; justify-content: space-between; align-items: center; .goods-pic { width: 100px; height: 100px; display: block; } }
3.封装名称为 showRadio 的 props 属性,来控制当前组件中是否显示 radio 组件:
// 儿子接受父亲传递过来的数据 props: { item: { type: Object, default: {} }, showRadio: { type: Boolean, default: false } },
4.使用v-show控制是否显示
<radio checked color="#C00000" v-show="showRadio"></radio>
5.需要展示的组件修改元素为true
<!-- 商品列表区域 --> <block v-for="(goods, i) in cart" :key="i"> <my-goods :goods="goods" :show-radio="true"></my-goods> </block>
6.修改 my-goods.vue 组件,动态为 radio 绑定选中状态:
<!-- 商品左侧图片区域 --> <view class="goods-item-left"> <!-- 存储在购物车中的商品,包含 goods_state 属性,表示商品的勾选状态 --> <radio :checked="goods.goods_state" color="#C00000" v-if="showRadio"></radio> <image :src="goods.goods_small_logo || defaultPic" class="goods-pic"></image> </view>
(4). 为 my-goods 组件封装 radio-change 事件
- 当用户点击
radio
组件,希望修改当前商品的勾选状态,此时用户可以为my-goods
组件绑定@radio-change
事件,从而获取当前商品的goods_id
和goods_state
:
<!-- 商品列表区域 --> <block v-for="(goods, i) in cart" :key="i"> <!-- 在 radioChangeHandler 事件处理函数中,通过事件对象 e,得到商品的 goods_id 和 goods_state --> <my-goods :goods="goods" :show-radio="true" @radio-change="radioChangeHandler"></my-goods> </block>
- 定义 radioChangeHandler 事件处理函数如下:
methods: { // 商品的勾选状态发生了变化 radioChangeHandler(e) { console.log(e) // 输出得到的数据 -> {goods_id: 395, goods_state: false} } }
- 在
my-goods.vue
组件中,为radio
组件绑定@click
事件处理函数如下:
<!-- 商品左侧图片区域 --> <view class="goods-item-left"> <radio :checked="goods.goods_state" color="#C00000" v-if="showRadio" @click="radioClickHandler"></radio> <image :src="goods.goods_small_logo || defaultPic" class="goods-pic"></image> </view>
- 在 my-goods.vue 组件的 methods 节点中,定义
radioClickHandler
事件处理函数:
methods: { radioChangeHandler() { // 这里传递的是一个对象 this.$emit('radio-change', { goods_id: this.item.goods_id, goods_state: this.item.goods_state }) } }
(5).修改购物车中商品的勾选状态
- 在
store/cart.js
模块中,声明如下的mutations
方法,用来修改对应商品的勾选状态:
// 更新购物车中商品的勾选状态 updateGoodsState(state, goods) { // 根据 goods_id 查询购物车中对应商品的信息对象 const findResult = state.cart.find(x => x.goods_id === goods.goods_id) // 有对应的商品信息对象 if (findResult) { // 更新对应商品的勾选状态 findResult.goods_state = goods.goods_state // 持久化存储到本地 this.commit('m_cart/saveToStorage') }
- 在 cart.vue 页面中,导入 mapMutations 这个辅助函数,从而将需要的 mutations 方法映射到当前页面中使用:
import badgeMix from '@/mixins/tabbar-badge.js' import { mapState, mapMutations } from 'vuex' export default { mixins: [badgeMix], computed: { ...mapState('m_cart', ['cart']), }, data() { return {} }, methods: { ...mapMutations('m_cart', ['updateGoodsState']), // 商品的勾选状态发生了变化 radioChangeHandler(e) { this.updateGoodsState(e) }, }, }