vue+vuex实现购物车逻辑

vuex实现购物车基本业务逻辑(移动端)

在本购物车业务中用到了第三方组件库vant,使用之前要先安装并导入相关依赖
安装vant
npm i vant -S
导入组件
我们这里直接导入了所有组件,但是vant也支持按需引入
import Vant from ‘vant’;
import ‘vant/lib/index.css’;

Vue.use(Vant);

添加商品

商品列表页面


<template>
<!-- shoppingList.vue -->
<!-- 点击购物车图标触发点击事件,并把商品传进去 -->
	 <span @click="addShoppingCart(item)"><van-icon name="shopping-cart-o" /></span>
</template>

<script>
methods: {
    //点击事件 提交一个方法,在vuex中定义并处理
    //这里提交的是一个同步的commit方法,异步的提交方法为dispacth
    addShoppingCart(item){
      this.$store.commit("addShoppingCart",item)
    }
  },
</script>

在vuex的index.js页面定义业务逻辑

//index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

//取出本地存储保存的购物车数据
let cartItem = JSON.parse(localStorage.getItem("shoppingcart"))
//取出保存的全选按钮状态
let shoppingCartCheckAll = JSON.parse(localStorage.getItem("shoppingCartCheckAll"))

export default new Vuex.Store({
  state: {
      //定义购物车数组 如果本地取出则取本地,如果没有则取空
      shoppingCartItem: cartItem?cartItem:[],
      // 定义全选状态 如果本地取出则取本地,如果没有则取空
      shoppingCartCheckAll:shoppingCartCheckAll?shoppingCartCheckAll:false
  },
  mutations: {
      //定义添加购物车方法
    addShoppingCart(state, item) {
        //进行去重
      let index = state.shoppingCartItem.findIndex(ele => {
        return ele.id === item.id
      })
      //如果购物车中存在商品则让这个商品数量加1
      if (index !== -1) {
        state.shoppingCartItem[index].count += 1;
          //不存在商品则添加提交的商品
      } else {
          //定义商品选中状态
        item.checked = false
        state.shoppingCartItem.push(item)
      }
        //添加完毕后保存到本地
      localStorage.setItem("shoppingcart",JSON.stringify(state.shoppingCartItem))
    },
  }

购物车页面

全选状态切换

<template>
  <div>
      <!-- 定义一个商品格子子组件,并循环商品创建 -->
    <ShoppingCartItem
      v-for="(item,index) in data"
      :key="index"
      :item="item"
    />
    <div class="shopping_cart_submit">
      <van-submit-bar :price="this.$store.getters.totalPrice*100" button-text="提交订单">
        <!-- 全选按钮的状态在vuex中定义 -->
        <van-checkbox
          v-model="test"
        >全选</van-checkbox>
      </van-submit-bar>
    </div>
  </div>
</template>

<script>
import ShoppingCartItem from "../components/ShoppingCartItem";
export default {
  components: {
    ShoppingCartItem
  },
  data() {
    return {
        //接收vuex中的购物车商品列表数据
      data: this.$store.state.shoppingCartItem,
    };
  },
    // 由于vue中input的值双向绑定的数据必须在data中定义,所以采用计算属性的get和set定义双向绑定的值
  computed: {
    test:{
        // get方法获取vuex的数据并return
      get(){
        return this.$store.state.shoppingCartCheckAll
      },
        //set方法接收一个参数,这个参数就是绑定的布尔值
        //set会改变传过来的值
      set(v){
        //window.console.log(v)
          //提交一个方法 在vuex中定义并处理
        this.$store.commit("oncheckAll",v);
      }
    }
  },
};
</script>

<style scoped>
.van-submit-bar {
  position: fixed;
  margin-bottom: 64px;
}
</style>

全选状态切换业务逻辑
这里为了节省代码就不写其余业务的代码了

mutation:{
    oncheckAll(state,boolean) {
        //循环购物车数组。并把全选按钮的值赋值给商品的选中状态
      state.shoppingCartItem.forEach(ele=> (ele.checked = boolean))  
       //保存到本地
        localStorage.setItem("shoppingCartCheckAll",JSON.stringify(state.shoppingCartCheckAll))
      localStorage.setItem("shoppingcart",JSON.stringify(state.shoppingCartItem))
    }
}

商品选中状态切换

商品组件

<template>
  <div>
    <van-card
      :num="item.count"
      :price="item.price*item.count"
      :title="item.content"
      :thumb="item.image"
    >
      <div slot="tags">
<!-- 商品选中状态在添加商品时候添加进了商品对象中 双向绑定商品选中状态 提交一个方法 -->
        <van-checkbox v-model="item.checked" @change="onCheckItem"></van-checkbox>
      </div>
      <div slot="footer">
       <!-- 定义商品数量加减方法 -->
        <van-stepper v-model="item.count" @plus="addCount" @minus="minCount" />
      </div>
    </van-card>
  </div>
</template>

<script>
export default {
  props: {
    item: Object
  },
  data() {
    return {
    };
  },
  methods: {
      // 提交一个处理方法 在vuex中定义并处理
    onCheckItem() {
      this.$store.commit("onCheckItem");
    },
      // 商品数量加减方法
    addCount() {
      this.$store.commit("addCount", this.item);
    },
    minCount() {
      this.$store.commit("minCount", this.item);
    }
  }
};
</script>

商品选中状态切换逻辑

mutation:{
    onCheckItem(state){
      // 定义一个临时数组
      let tempArr = []
      // 循环购物车数组,并且添加进定义的空数组
      state.shoppingCartItem.forEach(ele=>{
        tempArr.push(ele)
      })
      // every循环定义的临时数组
      // every()方法,针对数组中的每一个元素进行比对
      // 只要有一个元素比对结果为false则返回false
      // 反之要所有的元素比对结果为true才为true
      let result = tempArr.every(ele=>{
        // 对数组中每一项的选中状态比较  是否为选中状态 也就是true
        return ele.checked == true
      })
      // 全选按钮的选中状态等于every方法返回的值
      // 如果返回true说明商品全部选中 反之则说明有未选中的
      // 所以可以直接让全选按钮的值等于every方法返回的数据
      state.shoppingCartCheckAll = result
      // 保存到本地
      localStorage.setItem("shoppingCartCheckAll",JSON.stringify(state.shoppingCartCheckAll))
      // 保存本地
     localStorage.setItem("shoppingcart",JSON.stringify(state.shoppingCartItem))
    },
}

商品数量加减

addCount(state,item){
      item.count++
      localStorage.setItem("shoppingcart",JSON.stringify(state.shoppingCartItem))
    },
    minCount(state,item){
      item.count--
      localStorage.setItem("shoppingcart",JSON.stringify(state.shoppingCartItem))
    },
}

商品总价计算

vuex中也有一个类似vue计算属性的方法 getters,我们可以在这里进行一些类似于计算属性的操作

getters: {
    // 总价计算
    totalPrice(state) {
      // 声明一个变量
      let totalPrice = 0
      // 循环购物车数组
      state.shoppingCartItem.forEach(ele => {
        // 如果选中则累加商品价格*商品数量
        if(ele.checked == true){
          totalPrice += ele.count * ele.price
        }
      })
      // 导出
      return totalPrice
    }

在vue中可以直接使用getters方法导出的数据

<template>
<van-submit-bar :price="this.$store.getters.totalPrice*100" button-text="提交订单">
</template>

这样一个购物车的基础功能就实现啦

上一篇:js的一些实用小案例


下一篇:[穿梭框][js]运用document.adoptNode方法,写出基础的穿梭框效果