• 【Vue项目复习笔记】将商品添加到购物车


    将商品添加到购物车要先监听购物车点击
    在DetailBottomBar.vue中监听

    <div class="cart" @click="addToCart">加入购物车</div>
    
    • 1
     methods:{
        addToCart(){
          this.$emit('addCart');
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    然后在Detail.vue的detail-bottom-bar标签中

    <detail-bottom-bar @addCart="addCart"></detail-bottom-bar>
    
    • 1

    在methods中

     addToCart(){
            //1.获取购物车需要展示的信息
          const product={}
          product.image=this.topImages[0]
          product.title=this.goods.title;
          product.desc=this.goods.desc;
          product.price=this.goods.realPrice;
          product.iid=this.iid;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述
    我们需要从详情页拿到商品的数据,然后在购物车里面显示,所以我们可以通过Vuex
    首先安装vuex

     npm install vuex@3.5.1 --save
    
    • 1

    然后在store文件夹中新建index.js

    import Vue from "vue";
    import Vuex from "vuex";
    
    //安装插件
    Vue.use(Vuex);
    
    //创建Store对象
    const state = {
      cartList: [],
    };
    const store = new Vuex.Store({
      state,
      mutations:{}
      actions:{}
      getters:{}
    });
    
    //挂载到Vuex实例上
    export default store;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    然后在main.js里面做一个导入。
    再到

    addToCart(){
    //2、将商品添加到购物车
    this.$store.cartList.push(product)
    
    • 1
    • 2
    • 3

    但是实际上能不能像上面这样做呢?不能,任何修改state里面的东西都要通过mutations

    mutations:{
        addCart(state, payload){
          state.cartList.push(payload)
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    然后在Detail.vue的methods中

    addToCart(){
    //2、将商品添加到购物车
    this.$store.commit('addCart',product)
    }
    
    • 1
    • 2
    • 3
    • 4

    在购物车里面还需要判断这个数据是否已经存在,类别不同,数量不能光往上加,还需要在mutations里面做判断

        addCart(state, payload){
          //1.查找之前数组是否有该商品
          let oldProduce=state.cartList.find(item=>item.iid===payload.iid)
    
          //2.判断oldProduce
          if(oldProduce){
            oldProduce.count+=1
          }else{
            payload.count=1
            state.cartList.push(payload)
          }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    下面我们验证一下:
    我们在detail中

      <ul>
          <li v-for="item in $store.state.cartList">{{item}}</li>
        </ul>
    
    
    • 1
    • 2
    • 3
    • 4

    最终的结果为:
    请添加图片描述
    总结:当我们点击添加购物车的时候,在方法中addCart方法先获取商品信息,再通过Vuex里的commit,调用的就是mutations里面的addCart,将商品拿到,然后判断之前有没有该商品,如果有的话,直接在之前的基础上加1,没有的话,设置其数量为1。

    对上述代码进行简单的重构:

    • mutations唯一的目的就是修改state的状态
    • mutations中的每个方法进可能完成的事情比较单一一点。

    但是在我们的mutations里面现在做了两件事情,既有可能是数量加1,又有可能是把一个新的商品添加进去。在我们的mutations的设计原则里面一般不让这样做,虽然这样做对代码来讲并没有影响,但是我们最好还是不要这样做。就让每个mutations做一件单一的事情。
    一般情况下,第一步修改我们某个操作的时候,最好是通过action,再到mutations,再来修改state。
    在这里插入图片描述
    所以有判断逻辑的东西我们放到actions里面

    actions:{
        addCart(state, payload){
          //1.查找之前数组是否有该商品
          let oldProduce=state.cartList.find(item=>item.iid===payload.iid)
    
          //2.判断oldProduce
          if(oldProduce){
            oldProduce.count+=1
          }else{
            payload.count=1
            state.cartList.push(payload)
          }
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    然后detail里面

     this.$store.commit('addCart',product)
    
    • 1

    这一句就不能这么写了,要用到dispatch

      this.$store.dispatch('addCart',product)
    
    • 1

    又dispatch第一个参数不是state,而是context,,所以有

    addCart(context, payload){
          //1.查找之前数组是否有该商品
          let oldProduce=context.state.cartList.find(item=>item.iid===payload.iid)
    
          //2.判断oldProduce
          if(oldProduce){
            oldProduce.count+=1
          }else{
            payload.count=1
            context.state.cartList.push(payload)
          }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    再次进行优化

      mutations:{
        addCounter(state,payload){
          payload.count++
        },
        addCart(state,payload){
          state.cartList.push(payload)
        }
      },
      actions:{
        addCart(context, payload){
          //1.查找之前数组是否有该商品
          let oldProduce=context.state.cartList.find(item=>item.iid===payload.iid)
    
          //2.判断oldProduce
          if(oldProduce){
            // oldProduce.count+=1
            context.commit('addCounter',oldProduce)
          }else{
            payload.count=1
            // context.state.cartList.push(payload)
            context.commit('addCart', payload)
          }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    这样我们的vuex能更好的做跟踪。
    接着我们接着再次做重构,新建mutations.js,action.js把它们相关的代码都抽出去。
    index.js如下

    import Vue from "vue";
    import Vuex from "vuex";
    import mutations from '@/store/mutations';
    import actions from '@/store/actions'
    
    Vue.use(Vuex);
    
    const state = {
      cartList: [],
    };
    const store = new Vuex.Store({
      state,
      mutations,
      actions,
    });
    
    export default store;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    接着我们还想将mutations中的addCounter,addCart抽成常量,新建mutation-types.js

    export const ADD_COUNTER='add_counter'
    export const ADD_CART='add_cart'
    
    
    • 1
    • 2
    • 3

    然后将其导入到actions和mutations

    import {
      ADD_COUNTER,
      ADD_CART
    } from './mutation-types'
    
    export default {
      addCart(context, payload){
        //1.查找之前数组是否有该商品
        let oldProduce=context.state.cartList.find(item=>item.iid===payload.iid)
    
        //2.判断oldProduce
        if(oldProduce){
          // oldProduce.count+=1
          context.commit('ADD_COUNTER',oldProduce)
        }else{
          payload.count=1
          // context.state.cartList.push(payload)
          context.commit('ADD_CART', payload)
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    import {
      ADD_COUNTER,
      ADD_CART
    } from './mutation-types'
    
    export default {
     [ADD_COUNTER](state,payload){
        payload.count++
      },
      [ADD_CART](state,payload){
        state.cartList.push(payload)
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    【对比学习】CUT模型论文解读与NCE loss代码解析
    Cpolar - 本地 WebUI 账号登录失败解决方案
    代码随想录day59
    【2 线性表】顺序表中负值排在前面。
    开源全方位运维监控工具:HertzBeat
    Eclipse如何搭建一个SpringBoot项目
    想要精通算法和SQL的成长之路 - 划分字母区间
    Vue3简单使用(一) --- 环境搭建
    从原理剖析带你理解Stream
    element-plus-自定义Dialog样式
  • 原文地址:https://blog.csdn.net/qq_40992225/article/details/126267704