青橙优购——加入购物车

54 阅读5分钟

0 创建 cart 分支

运行如下的命令,基于 master 分支在本地创建 cart 子分支,用来开发购物车相关的功能:

git checkout -b cart

1 配置 vuex

  1. 在项目根目录中创建 store 文件夹,专门用来存放 vuex 相关的模块

  2. 在 store 目录上鼠标右键,选择 新建 -> js文件,新建 store.js 文件:

image.png

  1. 在 store.js 中按照如下 4 个步骤初始化 Store 的实例对象

image.png

  1. 在 main.js 中导入 store 实例对象并挂载到 Vue 的实例上:

    // 1. 导入 store 的实例对象
    import store from './store/store.js'
    
    // 省略其它代码...
    
    const app = new Vue({
      ...App,
      // 2. 将 store 挂载到 Vue 实例上
      store,
    })
    app.$mount()
    

2 创建购物车的 store 模块

  1. 在 store 目录上鼠标右键,选择 新建 -> js文件,创建购物车的 store 模块,命名为 cart.js

image.png 2. 在 cart.js 中,初始化如下的 vuex 模块:

image.png

  1. 在 store/store.js 模块中,导入并挂载购物车的 vuex 模块,示例代码如下:

image.png

3 在商品详情页中使用 Store 中的数据

  1. 在 goods_detail.vue 页面中,修改 <script></script> 标签中的代码如下:

    // 从 vuex 中按需导出 mapState 辅助方法
    import { mapState } from 'vuex'
    
    export default {
      computed: {
        // 调用 mapState 方法,把 m_cart 模块中的 cart 数组映射到当前页面中,作为计算属性来使用
        // ...mapState('模块的名称', ['要映射的数据名称1', '要映射的数据名称2'])
        ...mapState('m_cart', ['cart']),
      },
      // 省略其它代码...
    }
    

    注意:今后无论映射 mutations 方法,还是 getters 属性,还是 state 中的数据,都需要指定模块的名称,才能进行映射。

  2. 在页面渲染时,可以直接使用映射过来的数据,例如:

    <!-- 运费 -->
    <view class="yf">快递:免运费 -- {{cart.length}}</view>
    

4 实现加入购物车的功能

  1. 在 store 目录下的 cart.js 模块中,封装一个将商品信息加入购物车的 mutations 方法,命名为 addToCart。示例代码如下: image.png
  2. 在商品详情页面中,通过 mapMutations 这个辅助方法,把 vuex 中 m_cart 模块下的 addToCart 方法映射到当前页面:

image.png

  1. 为商品导航组件 uni-goods-nav 绑定 @buttonClick="buttonClick" 事件处理函数:

image.png

5 动态统计购物车中商品的总数量

  1. 在 cart.js 模块中,在 getters 节点下定义一个 total 方法,用来统计购物车中商品的总数量:

image.png 2. 在商品详情页面的 script 标签中,按需导入 mapGetters 方法并进行使用:

```
// 按需导入 mapGetters 这个辅助方法
import { mapGetters } from 'vuex'

export default {
  computed: {
    // 把 m_cart 模块中名称为 total 的 getter 映射到当前页面中使用
    ...mapGetters('m_cart', ['total']),
  },
}
```

3. 通过 watch 侦听器,监听计算属性 total 值的变化,从而动态为购物车按钮的徽标赋值

image.png

持久化存储购物车中的商品

  1. 在 cart.js 模块中,声明一个叫做 saveToStorage 的 mutations 方法,此方法负责将购物车中的数据持久化存储到本地:

  2. 修改 mutations 节点中的 addToCart 方法,在处理完商品信息后,用commit方法调用步骤 1 中定义的 saveToStorage 方法:

这里箭头函数写错了,判断的话不要加花括号 image.png 正确写法

image.png

  1. 修改 cart.js 模块中的 state 函数,读取本地存储的购物车数据,对 cart 数组进行初始化:

image.png

优化商品详情页的 total 侦听器

  1. 使用普通函数的形式定义的 watch 侦听器,在页面首次加载后不会被调用。因此导致了商品详情页在首次加载完毕之后,不会将商品的总数量显示到商品导航区域:

image.png

  1. 为了防止这个上述问题,可以使用对象的形式来定义 watch 侦听器(详细文档请参考 Vue 官方的 watch 侦听器教程),示例代码如下:

image.png

动态为 tabBar 页面设置数字徽标

需求描述:从商品详情页面导航到购物车页面之后,需要为 tabBar 中的购物车动态设置数字徽标。

  1. 把 Store 中的 total 映射到 cart.vue 中使用:

    // 按需导入 mapGetters 这个辅助方法
    import { mapGetters } from 'vuex'
    
    export default {
    
      data() {
        return {}
      },
      computed: {
        // 将 m_cart 模块中的 total 映射为当前页面的计算属性
        ...mapGetters('m_cart', ['total']),
      },
    }
    
  2. 在页面刚显示出来的时候,立即调用 setBadge 方法,为 tabBar 设置数字徽标:

    onShow() {
       // 在页面刚展示的时候,设置数字徽标
       this.setBadge()
    }
    
  3. 在 methods 节点中,声明 setBadge 方法如下,通过 uni.setTabBarBadge() 为 tabBar 设置数字徽标:

    methods: {
       setBadge() {
          // 调用 uni.setTabBarBadge() 方法,为购物车设置右上角的徽标
          uni.setTabBarBadge({
             index: 2, // 索引
             text: this.total + '' // 注意:text 的值必须是字符串,不能是数字
          })
       }
    }
    

将设置 tabBar 徽标的代码抽离为 mixins

注意:除了要在 cart.vue 页面中设置购物车的数字徽标,还需要在其它 3 个 tabBar 页面中,为购物车设置数字徽标。

此时可以使用 Vue 提供的 mixins 特性,提高代码的可维护性。

  1. 在项目根目录中新建 mixins 文件夹,并在 mixins 文件夹之下新建 tabbar-badge.js 文件,用来把设置 tabBar 徽标的代码封装为一个 mixin 文件:(cart.vue里js的内容,去掉cart.vue的内容)

image.png

  1. 修改 home.vuecate.vuecart.vuemy.vue 这 4 个 tabBar 页面的源代码,分别导入 @/mixins/tabbar-badge.js 模块并进行使用:

    // 导入自己封装的 mixin 模块
    import badgeMix from '@/mixins/tabbar-badge.js'
    
    export default {
      // 将 badgeMix 混入到当前的页面中进行使用
      mixins: [badgeMix],
      // 省略其它代码...
    }
    
      1. 开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 19天,点击查看活动详情