青橙优购——结算区域

50 阅读3分钟

1 把结算区域封装为组件

  1. 在 components 目录中,新建 my-settle 结算组件:

  2. 初始化 my-settle 组件的基本结构和样式:

image.png

  1. 在 cart.vue 页面中使用自定义的 my-settle 组件,并美化页面样式,防止页面底部被覆盖(外层加padding-bottom:50px):

image.png

2 渲染结算区域的结构和样式

  1. 定义如下的 UI 结构:

image.png

3 动态渲染已勾选商品的总数量,总价格

  1. 在 store/cart.js 模块中,定义一个名称为 checkedCount 的 getters,用来统计已勾选商品的总数量:(这里可以看到实际state和getters中的数据、函数可直接在页面中当数据来用。filter进行过滤选中的数据,find用来判断数组中是否有这个东西,有就返回对应的数组中的那一项)

image.png 2. 在 my-settle 组件中,通过 mapGetters 辅助函数,将需要的 getters 映射到当前组件中使用,将 checkedCount 的值渲染到页面中::

image.png

4 渲染购物车为空时的页面结构

  1. 改造 cart.vue 页面的 UI 结构,使用 v-if 和 v-else 控制购物车区域空白购物车区域的按需展示:

image.png

5 动态渲染全选按钮的选中状态

  1. 使用 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 {}
      },
    }
    
  2. 为 radio 组件动态绑定 checked 属性的值:

    <!-- 全选区域 -->
    <label class="radio">
      <radio color="#C00000" :checked="isFullCheck" /><text>全选</text>
    </label>
    

6 实现商品的全选/反选功能

  1. 在 store/cart.js 模块中,定义一个叫做 updateAllGoodsState 的 mutations 方法,用来修改所有商品的勾选状态:

    // 更新所有商品的勾选状态
    updateAllGoodsState(state, newState) {
      // 循环更新购物车中每件商品的勾选状态
      state.cart.forEach(x => x.goods_state = newState)
      // 持久化存储到本地
      this.commit('m_cart/saveToStorage')
    }
    
  2. 在 my-settle 组件中,通过 mapMutations 辅助函数,将需要的 mutations 方法映射到当前组件中使用: ·

    // 1. 按需导入 mapMutations 辅助函数
    import { mapGetters, mapMutations } from 'vuex'
    
    export default {
      // 省略其它代码
      methods: {
        // 2. 使用 mapMutations 辅助函数,把 m_cart 模块提供的 updateAllGoodsState 方法映射到当前组件中使用
        ...mapMutations('m_cart', ['updateAllGoodsState']),
      },
    }
    
  3. 为 UI 中的 label 组件绑定 click 事件处理函数:

    <!-- 全选区域 -->
    <label class="radio" @click="changeAllState">
      <radio color="#C00000" :checked="isFullCheck" /><text>全选</text>
    </label>
    
  4. 在 my-settle 组件的 methods 节点中,声明 changeAllState 事件处理函数:

    methods: {
      ...mapMutations('m_cart', ['updateAllGoodsState']),
      // label 的点击事件处理函数
      changeAllState() {
        // 修改购物车中所有商品的选中状态
        // !this.isFullCheck 表示:当前全选按钮的状态取反之后,就是最新的勾选状态
        this.updateAllGoodsState(!this.isFullCheck)
      }
    }
    

7 点击结算按钮进行条件判断

说明:用户点击了结算按钮之后,需要先后判断是否勾选了要结算的商品是否选择了收货地址是否登录

  1. 在 my-settle 组件中,为结算按钮绑定点击事件处理函数:

    <!-- 结算按钮 -->
    <view class="btn-settle" @click="settlement">结算({{checkedCount}})</view>
    
  2. 在 my-settle 组件的 methods 节点中声明 settlement 事件处理函数如下:

  • 先在main.js中封装

    image.png

  • 用这个组件 image.png

  1. 在 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
        },
      },
    }
    
  2. 在 store/user.js 模块的 state 节点中,声明 token 字符串:

    image.png

  3. 在 my-settle 组件中,使用 mapState 辅助函数,从 m_user 模块中将 token 映射到当前组件中使用:

    image.png