vue开发中购物车逻辑总结

添加购物车后同步修改购物车徽标的显示数量

  1. 因为涉及到组件之间的传值,我将需要传递的数据,放在Vuex中,可以方便供整个Vue实例使用/修改。
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({})
  1. 使用change事件监听购买数量input框的修改,使用$emit触发父组件方法,将input修改数据传递父组件data中selectedNum存储(默认数据为1)。

//子组件change方法
selectNum() {
  this.$emit("getSelectedNum", parseInt(this.$refs.num.value));
 }
 //父组件data数据
 data() {
    return {
      selectedNum: 1
    };
  1. 添加购物到车绑定点击事件,在事件处理函数中手动定义对象,对象包含商品id、商品数量、商品价格以及选中状态(默认为true),因为需要在购物车界面根据选中状态判断是否勾选购买商品,然后通过this.$store.commit('addToCar',goodsInfo)调用Vuex中定义的addToCar方法(方法在步骤4中定义),且将定义的goodsInfo传递过去。
添加购物车
addShopCar() {
      var goodsInfo = {
        id: this.id,
        count: this.selectedNum,
        price: this.infoList.sell_price,
        selected: true
      };
      this.$store.commit("addToCar", goodsInfo);
    },
	
  1. 需要在new Vue.store的mutations中定义添加购物车方法(addToCar),同时在state中定义加入购物车后的数据数组(car)。在addToCar中接收商品信息对象(goodsInfo),然后通过findIndex方法循环state.caraddToCar(state, goodsInfo) { var index = state.car.findIndex(item => item.id == goodsInfo.id),判断index,若为-1,将goodsInfo对象push到state.car中存储,若不为-1证明数据存在,此时将数据进行更新,state.car [index].count +=parseInt(goodsInfo.count), state.car[index].price = goodsInfo.price, state.car[index].selected = goodsInfo.selected,因为是本地临时数据,需要调用localStorage.setIten('car',Json.stringify(state.car))存储在localStorage中,页面加载时同样需要将购物车数据显示,所以在new Vuex.store前调用localStorage.getItem获取一下存储数据var car = JSON.parse(localStorage.getItem('car') || '[]'),将获取到的car拼接在state的car中,若为第一次加载界面会存在localStorage中没有数据,此时返回一个空数组,不会导致运行报错。
var car = JSON.parse(localStorage.getItem('car') || '[]')
const store = new Vuex.Store({
state: {
    car: car
  },
	addToCar(state, goodsInfo) {
      var i = state.car.findIndex(item => item.id == goodsInfo.id)
      if (i == -1) {
        state.car.push(goodsInfo)
      } else {
        state.car[i].count += parseInt(goodsInfo.count)
        state.car[i].price = goodsInfo.price
        state.car[i].selected = goodsInfo.selected
      }
      localStorage.setItem('car', JSON.stringify(state.car))
	})
  1. 最后在显示购物车徽标的组件中使用差值表达式对显示的数量进行渲染,然后在商品详情界面添加购物车操作,同时购物车的徽标会跟随你的添加数量而改变。

购物车界面逻辑

  1. 购物车界面同样可以对商品的购买数量进行修改,所以同样需要对购买数量的input框绑定change事件,在change事件中需要将商品的id作为参数传递同时还有input的value值(参数需要以对象形式传递)。因为我的购买数量选择框为子组件,所以我使用属性绑定将商品id传递给子组件。
 
 methods: {
    changed(){
      this.$store.commit('updateGoodsInfo', {
        id: this.goodsid,
        count: this.$refs.num.value
      })
    }
  },
  //父组件
  import numbox from "../subcomponents/shopcar_numbox.vue";
  components: {
    numbox
  },
  //子组件渲染
  
  1. 在vuex中定义updateGoodsInfo方法,因为在购物车界面的数量修改与商品详情界面业务不一样,所以我重新定义一个新方法,处理购物车界面数量修改的业务逻辑,在updateGoodsInfo方法中同样需要循环state中carupdateGoodsInfo(state,obg){state.car.some(item=>{if(item.id == obj.id){item.count=parseInt(obj.count)return true}})localStorage.setItem('car', JSON.stringify(state.car))}因为数据修改,需要重新调用localStorage的setItem方法重新设置一下购物车数量显示。此时会在徽标显示的数量的基础上进行修改显示。
updateGoodsInfo(state, obj) {
      state.car.some(item => {
        if (item.id == obj.id) {
          item.count = parseInt(obj.count)
          return true
        }
      })
      localStorage.setItem('car', JSON.stringify(state.car))
    },
  1. 删除功能,给删除按钮添加点击事件,将商品id与数据索引作为参数传递,调用数据的splice方法将选中的某条数据删除。同时调用vuex中的removeGoodsList方法删除本地存储的数据,此时只需要将商品id作为参数传递即可。
删除
removeGoodsList(id, index) {
      this.shopCarList.splice(index, 1);
      this.$store.commit("removeGoodsList", id);
    },
  1. 在vuex中定义removeGoodsList方法,同样需要循环state.carremoveGoodsList(state, id) { state.car.some((item, index) => { if (item.id == id) { state.car.splice(index, 1) } }) localStorage.setItem('car', JSON.stringify(state.car)) },,因为数据改变,所以再次调用 localStorage.setItem(‘car’, JSON.stringify(state.car))重新设置存储数据。
  //vuex中删除的方法
    removeGoodsList(state, id) {
      state.car.some((item, index) => {
        if (item.id == id) {
          state.car.splice(index, 1)
        }
      })
      localStorage.setItem('car', JSON.stringify(state.car))
    },
  1. 购物车商品选中状态,在store的getters中定义 getGoodsSelected(state) { var o = {} state.car.forEach(item => { o[item.id] = item.selected }) return o },将某个商品的id与选中状态以对象返回,我这边在购物车组件中的选中框样式使用的是mint-ui,在mt-switch中可以使用change api触发selectedChange方法,参数有商品id以及 s t o r e . g e t t e r s . g e t G o o d s S e l e c t e d [ i t e m . i d ] 的 选 中 状 态 ‘ < m t − s w i t c h @ c h a n g e = " s e l e c t e d C h a n g e ( i t e m . i d , store.getters.getGoodsSelected[item.id]的选中状态`<mt-switch @change="selectedChange(item.id, store.getters.getGoodsSelected[item.id]<mtswitch@change="selectedChange(item.id,store.getters.getGoodsSelected[item.id])"
    v-model="$store.getters.getGoodsSelected[item.id]"
    >`,同时使用v-model绑定选中状态。
getGoodsSelected(state) {
      var o = {}
      state.car.forEach(item => {
        o[item.id] = item.selected
      })
      return o
    },
    //购物车界面
    
  1. 在change触发的方法中同时调用store中的updateGoodsSelected方法同时需要将商品id与选中状态以对象形式传递,再次循环car如果id相等,让car的选中状态与购物车界面组件的选中状态同步。
`selectedChange(id, val) {
      this.$store.commit("updateGoodsSelected", { id, selected: val });
    }`
updateGoodsSelected(state, obj) {
      state.car.some(item => {
        if (item.id == obj.id) {
          item.selected = obj.selected
        }
      })
      localStorage.setItem('car', JSON.stringify(state.car))
    }
  1. 最后将购物车界面的合计与勾选数量进行处理,store.getters将count,amount以对象形式return,在购物车界面使用差值表达式对数据渲染
getGoodsCountAndAmount(state) {
      var o = {
        count: 0,
        amount: 0
      }
      state.car.forEach(item => {
        o.count += item.count
        o.amount += item.price * item.count
      })
      return o
    }
{{$store.getters.getGoodsCountAndAmount.count}} 件,
总价¥{{$store.getters.getGoodsCountAndAmount.amount}}

你可能感兴趣的:(vue开发中购物车逻辑总结)