个人名片:
🐼作者简介:一名大二在校生,讨厌编程🎋
🐻❄️***个人主页🥇:***小新爱学习.
🐼***个人WeChat:见文末***
🕊️***系列专栏:🖼️***
- 零基础学Java——小白入门必备
- 重识C语言——复习回顾
- 计算机网络体系———深度详讲
- 微信小程序开发——实战开发
- 基于黑马优选的小程序开发实战教程
🐓***每日一句:🍭***好想赚钱!!!
文章目录
- 9.3 结算区域
- 9.3.1 把结算区域封装为组件
- 9.3.2 渲染结算区域的结构和样式
- 9.3.3 动态渲染已勾选商品的总数量
- 9.3.4 动态渲染全选按钮的选中状态
- 9.3.5 实现商品的全选/反选功能
- 9.3.6 动态渲染已勾选商品的总价格
- 9.3.7 动态计算购物车徽标的数值
- 9.3.8 渲染购物车为空时的页面结构
- 9.4 分支的合并与提交
- ==三连支持一下!==
9.3 结算区域
9.3.1 把结算区域封装为组件
- 在
components
目录中,新建my-settle
结算组件:
- 初始化
my-settle
组件的基本结构和样式:
<template>
<!-- 最外层的容器 -->
<view class="my-settle-container">
结算组件
</view>
</template>
<script>
export default {
data() {
return {}
},
}
</script>
<style lang="scss">
.my-settle-container {
/* 底部固定定位 */
position: fixed;
bottom: 0;
left: 0;
/* 设置宽高和背景色 */
width: 100%;
height: 50px;
background-color: cyan;
}
</style>
- 在
cart.vue
页面中使用自定义的my-settle
组件,并美化页面样式,防止页面底部被覆盖:
<template>
<view class="cart-container">
<!-- 使用自定义的 address 组件 -->
<!-- 购物车商品列表的标题区域 -->
<!-- 商品列表区域 -->
<!-- 结算区域 -->
<my-settle></my-settle>
</view>
</template>
<style lang="scss">
.cart-container {
padding-bottom: 50px;
}
</style>
9.3.2 渲染结算区域的结构和样式
- 定义如下的
UI
结构:
<!-- 最外层的容器 -->
<view class="my-settle-container">
<!-- 全选区域 -->
<label class="radio">
<radio color="#C00000" :checked="true" /><text>全选</text>
</label>
<!-- 合计区域 -->
<view class="amount-box">
合计:<text class="amount">¥1234.00</text>
</view>
<!-- 结算按钮 -->
<view class="btn-settle">结算(0)</view>
</view>
- 美化样式:
.my-settle-container {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 50px;
// 将背景色从 cyan 改为 white
background-color: white;
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 5px;
font-size: 14px;
.radio {
display: flex;
align-items: center;
}
.amount {
color: #c00000;
}
.btn-settle {
height: 50px;
min-width: 100px;
background-color: #c00000;
color: white;
line-height: 50px;
text-align: center;
padding: 0 10px;
}
}
9.3.3 动态渲染已勾选商品的总数量
- 在
store/cart.js
模块中,定义一个名称为checkedCount
的getters
,用来统计已勾选商品的总数量:
// 勾选的商品的总数量
checkedCount(state) {
// 先使用 filter 方法,从购物车中过滤器已勾选的商品
// 再使用 reduce 方法,将已勾选的商品总数量进行累加
// reduce() 的返回值就是已勾选的商品的总数量
return state.cart.filter(x => x.goods_state).reduce((total, item) => total += item.goods_count, 0)
}
- 在
my-settle
组件中,通过mapGetters
辅助函数,将需要的getters
映射到当前组件中使用:
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters('m_cart', ['checkedCount']),
},
data() {
return {}
},
}
- 将
checkedCount
的值渲染到页面中:
<!-- 结算按钮 -->
<view class="btn-settle">结算({{checkedCount}})</view>
9.3.4 动态渲染全选按钮的选中状态
- 使用
mapGetters
辅助函数,将商品的总数量映射到当前组件中使用,并定义一个叫做isFullCheck
的计算属性:
import { mapGetters } from 'vuex'
export default {
computed: {
// 1. 将 total 映射到当前组件中
...mapGetters('m_cart', ['checkedCount', 'total']),
// 2. 是否全选
isFullCheck() {
return this.total === this.checkedCount
},
},
data() {
return {}
},
}
- 为
radio
组件动态绑定checked
属性的值:
<!-- 全选区域 -->
<label class="radio">
<radio color="#C00000" :checked="isFullCheck" /><text>全选</text>
</label>
9.3.5 实现商品的全选/反选功能
- 在
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)
}
}
9.3.6 动态渲染已勾选商品的总价格
- 在
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>
9.3.7 动态计算购物车徽标的数值
1. 问题说明:当修改购物车中商品的数量之后,tabBar 上的数字徽标不会自动更新。
2. 解决方案:改造 mixins/tabbar-badge.js 中的代码,使用 watch 侦听器,监听 total 总数量的变化,从而动态为 tabBar 的徽标赋值:
import { mapGetters } from 'vuex'
// 导出一个 mixin 对象
export default {
computed: {
...mapGetters('m_cart', ['total']),
},
watch: {
// 监听 total 值的变化
total() {
// 调用 methods 中的 setBadge 方法,重新为 tabBar 的数字徽章赋值
this.setBadge()
},
},
onShow() {
// 在页面刚展示的时候,设置数字徽标
this.setBadge()
},
methods: {
setBadge() {
// 调用 uni.setTabBarBadge() 方法,为购物车设置右上角的徽标
uni.setTabBarBadge({
index: 2,
text: this.total + '', // 注意:text 的值必须是字符串,不能是数字
})
},
},
}
9.3.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.4 分支的合并与提交
- 将
cart
分支进行本地提交:
git add .
git commit -m "完成了购物车的开发"
- 将本地的
cart
分支推送到码云:
git push -u origin cart
- 将本地
cart
分支中的代码合并到master
分支:
git checkout master
git merge cart
git push
- 删除本地的
cart
分支:
git branch -d cart