uniapp-加入购物车配置
1.设置Store的实例对象
1.在项目根目录中创建 store
文件夹,专门用来存放 vuex
相关的模块
2.新建 store.js
文件并配置:
// 1. 导入 Vue 和 Vuex
import Vue from 'vue'
import Vuex from 'vuex'// 1. 导入购物车的 vuex 模块
import moduleCart from './cart.js'// 导入用户的 vuex 模块
import moduleUser from './user.js'// 2. 将 Vuex 安装为 Vue 的插件
Vue.use(Vuex)// 3. 创建 Store 的实例对象
const store = new Vuex.Store({// TODO:挂载 store 模块modules: {// 2. 挂载购物车的 vuex 模块,模块内成员的访问路径被调整为 m_cart,例如:// 购物车模块中 cart 数组的访问路径是 m_cart/cartm_cart: moduleCart,// 挂载用户的 vuex 模块,访问路径为 m_userm_user: moduleUser,},
})// 4. 向外共享 Store 的实例对象
export default store
2.设置购物车的示例模块
1.在 store.js
同目录下创建cart.js
。
2.实现加入购物车的功能addToCart
。
3.实现动态监听统计购物车中商品的总数量的total
方法。
4.实现购物车中的商品的持久化存储saveToStorage
。
export default {// 为当前模块开启命名空间namespaced: true,// 模块的 state 数据state: () => ({// 购物车的数组,用来存储购物车中每个商品的信息对象// 每个商品的信息对象,都包含如下 6 个属性:// { goods_id, goods_name, goods_price, goods_count, goods_small_logo, goods_state }cart: JSON.parse(uni.getStorageSync('cart') || '[]')}),// 模块的 mutations 方法mutations: {// 将购物车中的数据持久化存储到本地saveToStorage(state) {uni.setStorageSync('cart', JSON.stringify(state.cart))},addToCart(state, goods) {// 根据提交的商品的Id,查询购物车中是否存在这件商品// 如果不存在,则 findResult 为 undefined;否则,为查找到的商品信息对象const findResult = state.cart.find((x) => x.goods_id === goods.goods_id)if (!findResult) {// 如果购物车中没有这件商品,则直接 pushstate.cart.push(goods)} else {// 如果购物车中有这件商品,则只更新数量即可findResult.goods_count++}// 通过 commit 方法,调用 m_cart 命名空间下的 saveToStorage 方法this.commit('m_cart/saveToStorage')},// 更新购物车中商品的勾选状态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')}},// 更新购物车中商品的数量updateGoodsCount(state, goods) {// 根据 goods_id 查询购物车中对应商品的信息对象const findResult = state.cart.find(x => x.goods_id === goods.goods_id)if(findResult) {// 更新对应商品的数量findResult.goods_count = goods.goods_count// 持久化存储到本地this.commit('m_cart/saveToStorage')}},// 根据 Id 从购物车中删除对应的商品信息removeGoodsById(state, goods_id) {// 调用数组的 filter 方法进行过滤state.cart = state.cart.filter(x => x.goods_id !== goods_id)// 持久化存储到本地this.commit('m_cart/saveToStorage')},// 更新所有商品的勾选状态updateAllGoodsState(state, newState) {// 循环更新购物车中每件商品的勾选状态state.cart.forEach(x => x.goods_state = newState)// 持久化存储到本地this.commit('m_cart/saveToStorage')}},// 模块的 getters 属性getters: {// 统计购物车中商品的总数量total(state) {let c = 0// 循环统计商品的数量,累加到变量 c 中state.cart.forEach(goods => c += goods.goods_count)return c},// 勾选的商品的总数量checkedCount(state) {// 先使用 filter 方法,从购物车中过滤器已勾选的商品// 再使用 reduce 方法,将已勾选的商品总数量进行累加// reduce() 的返回值就是已勾选的商品的总数量return state.cart.filter(x => x.goods_state).reduce((total, item) => total += item.goods_count, 0)},// 已勾选的商品的总价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)}}
}
3.在商品详情页引入功能
1.引入store
的数据:
<script>// 从 vuex 中按需导出 mapState 辅助方法import { mapState } from 'vuex'export default {computed: {// 调用 mapState 方法,把 m_cart 模块中的 cart 数组映射到当前页面中,作为计算属性来使用// ...mapState('模块的名称', ['要映射的数据名称1', '要映射的数据名称2'])...mapState('m_cart', ['cart']),},}
</script>
2,引入store
的方法“商品添加到购物车addToCart
”,并为商品导航组件 uni-goods-nav
绑定 @buttonClick="buttonClick"
事件处理函数:
<script>// 按需导入 mapMutations 这个辅助方法import { mapMutations } from 'vuex'export default {methods: {// 把 m_cart 模块中的 addToCart 方法映射到当前页面使用...mapMutations('m_cart', ['addToCart']),// 右侧按钮的点击事件处理函数buttonClick(e) {// 1. 判断是否点击了 加入购物车 按钮if (e.content.text === '加入购物车') {// 2. 组织一个商品的信息对象const goods = {goods_id: this.goods_info.goods_id, // 商品的Idgoods_name: this.goods_info.goods_name, // 商品的名称goods_price: this.goods_info.goods_price, // 商品的价格goods_count: 1, // 商品的数量goods_small_logo: this.goods_info.goods_small_logo, // 商品的图片goods_state: true // 商品的勾选状态}// 3. 通过 this 调用映射过来的 addToCart 方法,把商品信息对象存储到购物车中this.addToCart(goods)}}},}
</script>
4.动态为 tabBar 页面设置数字徽标
1.在项目根目录中新建 mixins
文件夹,并在 mixins
文件夹之下新建 tabbar-badge.js
文件
2.将设置 tabBar
徽标的代码抽离为 mixins
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 的值必须是字符串,不能是数字})},},
}
3.修改 home.vue
,cate.vue
,cart.vue
,my.vue
这 4 个 tabBar
页面的源代码,分别导入 @/mixins/tabbar-badge.js
模块并进行使用:
// 导入自己封装的 mixin 模块
import badgeMix from '@/mixins/tabbar-badge.js'export default {// 将 badgeMix 混入到当前的页面中进行使用mixins: [badgeMix],// 省略其它代码...
}
5.效果
1.可以正常将商品加入/剔出购物车:
2.动态徽标显示购物车内商品数量: