(6). 实现商品的全选/反选功能
- 在
store/cart.js
模块中,定义一个叫做updateAllGoodsState
的mutations
方法,用来修改所有商品的勾选状态:
// 更新所有商品的勾选状态 updateAllGoodsState(state, newState) { // 循环更新购物车中每件商品的勾选状态 state.cart.forEach(x => x.goods_state = newState) // 持久化存储到本地 this.commit('m_cart/saveToStorage') }
- 在 my-settle 组件中,通过 mapMutations 辅助函数,将需要的 mutations 方法映射到当前组件中使用:
// 1. 按需导入 mapMutations 辅助函数 import { mapGetters, mapMutations } from 'vuex' export default { // 省略其它代码 methods: { // 2. 使用 mapMutations 辅助函数,把 m_cart 模块提供的 updateAllGoodsState 方法映射到当前组件中使用 ...mapMutations('m_cart', ['updateAllGoodsState']), }, }
- 为 UI 中的 label 组件绑定 click 事件处理函数:
<!-- 全选区域 --> <label class="radio" @click="changeAllState"> <radio color="#C00000" :checked="isFullCheck" /><text>全选</text> </label>
- 在 my-settle 组件的 methods 节点中,声明 changeAllState 事件处理函数:
methods: { ...mapMutations('m_cart', ['updateAllGoodsState']), // label 的点击事件处理函数 changeAllState() { // 修改购物车中所有商品的选中状态 // !this.isFullCheck 表示:当前全选按钮的状态取反之后,就是最新的勾选状态 this.updateAllGoodsState(!this.isFullCheck) } }
(7). 动态渲染已勾选商品的总价格
- 在 store/cart.js 模块中,定义一个叫做 checkedGoodsAmount 的 getters,用来统计已勾选商品的总价格:
// 已勾选的商品的总价 checkedGoodsAmount(state) { // 先使用 filter 方法,从购物车中过滤器已勾选的商品 // 再使用 reduce 方法,将已勾选的商品数量 * 单价之后,进行累加 // reduce() 的返回值就是已勾选的商品的总价 // 最后调用 toFixed(2) 方法,保留两位小数 return state.cart.filter(x => x.goods_state) .reduce((total, item) => total += item.goods_count * item.goods_price, 0) .toFixed(2) }
- 在 my-settle 组件中,使用 mapGetters 辅助函数,把需要的 checkedGoodsAmount 映射到当前组件中使用:
...mapGetters('m_cart', ['total', 'checkedCount', 'checkedGoodsAmount'])
- 在组件的 UI 结构中,渲染已勾选的商品的总价:
<!-- 合计区域 --> <view class="amount-box"> 合计:<text class="amount">¥{{checkedGoodsAmount}}</text> </view>
(8).渲染购物车为空时的页面结构
- 将 资料 目录中的 cart_empty@2x.png 图片复制到项目的 /static/ 目录中
- 改造 cart.vue 页面的 UI 结构,使用 v-if 和 v-else 控制购物车区域和空白购物车区域的按需展示:
<template> <view class="cart-container" v-if="cart.length !== 0"> <!-- 使用自定义的 address 组件 --> <!-- 购物车商品列表的标题区域 --> <!-- 商品列表区域 --> <!-- 结算区域 --> </view> <!-- 空白购物车区域 --> <view class="empty-cart" v-else> <image src="/static/cart_empty@2x.png" class="empty-img"></image> <text class="tip-text">空空如也~</text> </view> </template>
- 美化空白购物车区域的样式:
.empty-cart { display: flex; flex-direction: column; align-items: center; padding-top: 150px; .empty-img { width: 90px; height: 90px; } .tip-text { font-size: 12px; color: gray; margin-top: 15px; } }
(9).分支的合并与提交
git add . git commit -m "完成购物车的开发" git push -u origin cart
git checkout master git add . git commit -m "完成购物车的开发" git merge cart git push git branch -d cart
12.配置页面 - 登入与支付
(1).创建settle分支
git checkout -b settle
(2). 点击结算按钮进行条件判断
说明:用户点击了结算按钮之后,需要先后判断是否勾选了要结算的商品、是否选择了收货地址、是否登录。
- 在 my-settle 组件中,为结算按钮绑定点击事件处理函数:
<!-- 结算按钮 --> <view class="btn-settle" @click="settlement">结算({{checkedCount}})</view>
- 在 my-settle 组件的 methods 节点中声明 settlement 事件处理函数如下:
// 点击了结算按钮 settlement() { // 1. 先判断是否勾选了要结算的商品 if (!this.checkedCount) return uni.$showMsg('请选择要结算的商品!') // 2. 再判断用户是否选择了收货地址 if (!this.addstr) return uni.$showMsg('请选择收货地址!') // 3. 最后判断用户是否登录了 if (!this.token) return uni.$showMsg('请先登录!') }
- 在 my-settle 组件中,使用 mapGetters 辅助函数,从 m_user 模块中将 addstr 映射到当前组件中使用:
export default { computed: { ...mapGetters('m_cart', ['total', 'checkedCount', 'checkedGoodsAmount']), // addstr 是详细的收货地址 ...mapGetters('m_user', ['addstr']), isFullCheck() { return this.total === this.checkedCount }, }, }
- 在 store/user.js 模块的 state 节点中,声明 token 字符串:
export default { // 开启命名空间 namespaced: true, // state 数据 state: () => ({ // 收货地址 address: JSON.parse(uni.getStorageSync('address') || '{}'), // 登录成功之后的 token 字符串 token: '', }), // 省略其它代码 }
- 在 my-settle 组件中,使用 mapState 辅助函数,从 m_user 模块中将 token 映射到当前组件中使用
// 按需从 vuex 中导入 mapState 辅助函数 import { mapGetters, mapMutations, mapState } from 'vuex' export default { computed: { ...mapGetters('m_cart', ['total', 'checkedCount', 'checkedGoodsAmount']), ...mapGetters('m_user', ['addstr']), // token 是用户登录成功之后的 token 字符串 ...mapState('m_user', ['token']), isFullCheck() { return this.total === this.checkedCount }, }, }
(3).登入页面
- 点击 微信开发者工具 工具栏上的编译模式下拉菜单,选择 添加编译模式:
(4). 实现登录和用户信息组件的按需展示
- 在 components 目录中新建登录组件:
- 在 components 目录中新建用户信息组件:
新增组件一定要重新更新
3. 在 my.vue 页面中,通过 mapState 辅助函数,导入需要的 token 字符串*并进行按需判断:
<template> <view> <!-- 为登入的时候展示 空字符串白默认为false --> <my-login v-if="!tocken"></my-login> <!-- 登入的时候展示 --> <my-userinfo v-else></my-userinfo> </view> </template> <script> import badgeMix from '@/mixins/tabbar-badge.js' import { mapState } from "vuex" export default { mixins: [badgeMix], computed: { ...mapState('m_user', ['tocken']) }, data() { return { }; } } </script> <style lang="scss"> </style>
(5).实现登入组件的基本布局
my-login.vue
<template> <view class="login-container"> <!-- 提示登录的图标 --> <uni-icons type="contact-filled" size="100" color="#AFAFAF"></uni-icons> <button type="primary" class="btn-login">一键登入</button> <text class="tips-text">登入后尽享更多权益</text> </view> </template> <script> export default { name: "my-login", data() { return { }; } } </script> <style lang="scss"> .login-container { height: 750rpx; background-color: #f8f8f8; display: flex; flex-direction: column; justify-content: center; align-items: center; .contact-filled {} .btn-login { width: 90%; // 圆角 border-radius: 100px; margin: 15px 0; background-color: #c00000; } .tips-text { font-size: 14px; color: gray; } } </style>
(6).点击登录按钮获取微信用户的基本信息
需求描述:需要获取微信用户的头像、昵称等基本信息。
- 为登录的 button 按钮绑定
open-type="getUserInfo"
属性,表示点击按钮时,希望获取用户的基本信息: