前端学习(三):Vuex购物车案例

117 阅读2分钟

前文

今天我们通过一个黑马程序员的一个小案例,来继续巩固Vuex方面的知识

image.png

代码实现

(1)数据准备、获取、渲染部分

建立仓库以及对应模块

index.js

import Vue from 'vue'
import Vuex from 'vuex'
import cart from './modules/cart'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    cart
  }
})

cart.js

import axios from 'axios'
export default {
  namespaced: true,
  state () {
    return {
      // 购物车数据 [{}, {}]
      list: []
    }
  },
  mutations: {
    updateList (state, newList) {
      
    },
    updateCount (state, obj) {
     
    }
  },
  actions: {
    }
    async updateCountAsync (context, obj) {
  },
  getters: {
  }
}

准备后台数据

image.png

index.json文件

{
  "cart": [
    {
      "id": 100001,
      "name": "低帮城市休闲户外鞋天然牛皮COOLMAX纤维",
      "price": 128,
      "count": 5,
      "thumb": "https://yanxuan-item.nosdn.127.net/3a56a913e687dc2279473e325ea770a9.jpg"
    },
    {
      "id": 100002,
      "name": "网易味央黑猪猪肘330g*1袋",
      "price": 39,
      "count": 10,
      "thumb": "https://yanxuan-item.nosdn.127.net/d0a56474a8443cf6abd5afc539aa2476.jpg"
    },
    {
      "id": 100003,
      "name": "KENROLL男女简洁多彩一片式室外拖",
      "price": 128,
      "count": 3,
      "thumb": "https://yanxuan-item.nosdn.127.net/eb1556fcc59e2fd98d9b0bc201dd4409.jpg"
    },
    {
      "id": 100004,
      "name": "云音乐定制IN系列intar民谣木吉他",
      "price": 589,
      "count": 1,
      "thumb": "https://yanxuan-item.nosdn.127.net/4d825431a3587edb63cb165166f8fc76.jpg"
    }
  ],
  "friends": [
    {
      "id": 1,
      "name": "zs",
      "age": 18
    },
    {
      "id": 2,
      "name": "ls",
      "age": 19
    },
    {
      "id": 3,
      "name": "ww",
      "age": 20
    }
  ]
}

请求数据

image.png

渲染数据

1.设置数组存储请求数据

image.png

2.使用actinos和mutations方法,请求数据,并且保存

image.png

image.png

3.在App.Vue组件中调用触发请求数据的方法,并且传递给子组件进行渲染

image.png

(2)修改数据数量

1.在cart-item组件通过点击事件调用actions方法传递身份识别id以及更新后的数量(以对象传递,actions方法只能传递一个形参)

<template>
  <div class="goods-container">
    <!-- 左侧图片区域 -->
    <div class="left">
      <img :src="item.thumb" class="avatar" alt="">
    </div>
    <!-- 右侧商品区域 -->
    <div class="right">
      <!-- 标题 -->
      <div class="title">{{ item.name }}</div>
      <div class="info">
        <!-- 单价 -->
        <span class="price">¥{{ item.price }}</span>
        <div class="btns">
          <!-- 按钮区域 -->
          <button class="btn btn-light" @click="btnClick(-1)">-</button>
          <span class="count">{{ item.count }}</span>
          <button class="btn btn-light" @click="btnClick(1)">+</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'CartItem',
  methods: {
    btnClick (step) {
      const newCount = this.item.count + step
      const id = this.item.id
      if (newCount < 1) return
      this.$store.dispatch('cart/updateCountAsync', {
        id: id,
        count: newCount
      })
    }
  },
  props: {
    item: {
      type: Object,
      required: true
    }
  }
}
</script>

<style lang="less" scoped>
.goods-container {
  display: flex;
  padding: 10px;
  + .goods-container {
    border-top: 1px solid #f8f8f8;
  }
  .left {
    .avatar {
      width: 100px;
      height: 100px;
    }
    margin-right: 10px;
  }
  .right {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    flex: 1;
    .title {
      font-weight: bold;
    }
    .info {
      display: flex;
      justify-content: space-between;
      align-items: center;
      .price {
        color: red;
        font-weight: bold;
      }
      .btns {
        .count {
          display: inline-block;
          width: 30px;
          text-align: center;
        }
      }
    }
  }
}

.custom-control-label::before,
.custom-control-label::after {
  top: 3.6rem;
}
</style>

2.在cart.js中通过actions方法接受参数,并且发起patch请求更新后台数据库和commit关键字调用mutation方法更新Vuex仓库

image.png

image.png

(3)计算商品总数量与总价

1.总数量计算

在Getters中使用递归,统计数量之和

image.png

2.总价计算

在Getters中使用递归,统计 商品和价格乘积

image.png