Vuex 购物车demo

本文介绍了一个使用Vue框架实现的购物车应用案例,包括组件化设计、状态管理与Vuex的结合使用,展示了如何通过Vue和Vuex进行产品展示、添加到购物车及计算总价等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 文件结构

App.vue

<template>
  <div id="app">
    <h3>Shopping Cart Demo</h3>
    <hr>
    <h4>Products:</h4>
    <ProductList />
    <hr>
    <h4>My Cart</h4>
    <ShoppingCart />
  </div>
</template>
<script>
import ProductList from '@/components/ProductList';
import ShoppingCart from  '@/components/ShoppingCart';

export default {
  components: {
    ProductList,
    ShoppingCart
  }
}
</script>

Products.vue

<template>
  <div>
     <ul v-for="item in products" :key="item.id">
       <li>
         {{ item.title }} - {{ item.price }} &nbsp;&nbsp; 库存: {{ item.inventory }}<br>
         <button :disabled="!item.inventory" @click="addToCart(item)">add to cart</button>  
       </li>
     </ul>
  </div>
  
</template>

<script>
import { mapGetters, mapActions } from 'vuex';
export default {
  computed: {
    // ...mapGetters('products',{
    //   products: 'allProducts'
    // })
    ...mapGetters({
      products: 'products/allProducts'
    })
  },
  methods: {
    ...mapActions('cart',['addToCart'])
  },
  created() {
    this.$store.dispatch('products/getAllProducts');
  }
  
}
</script>

ShoppingCart.vue

<template>
  <div>
    <ul v-for="item in products" :key="item.id">
      <li>{{ item.title }} *{{ item.quantity }}</li>
    </ul>
    <div>total: {{ total }}</div>
  </div>
</template>
<script>
import { mapGetters } from 'vuex';
export default {
  computed: {
    ...mapGetters('cart', {
      products: 'cartProducts',
      total: 'cartTotalPrice'
    })
  }
}
</script>

modules/products.js

import api from '../../api';

const state = {
  all: []
}

const getters = {
  allProducts: state => state.all
}

const actions = {
  // 获取初始商品数据
  getAllProducts({ commit }) {
    api.getProducts(products => commit('setProducts', products));
  }
}

const mutations = {
  setProducts(state, products) {
    state.all = products;
  },
  // 减少该商品库存
  decreamentInventory(state, { id }) {
    let productItem = state.all.find(item => item.id === id);
    productItem.inventory --;
  }
}

export default {
  namespaced: true,
  state,
  getters,
  actions,
  mutations
}

modules/cart.js

const state = {
  addedList: []
}

const getters = {
  cartProducts(state, getters, rootState) {
    return state.addedList.map((item, index) => {
      let productItem = rootState.products.all.find(product => product.id === item.id);
      return {
        title: productItem.title,
        price: productItem.price,
        quantity: item.quantity
      }
    })
  },
  cartTotalPrice(state, getters) {
    return getters.cartProducts.reduce((total, product) => {
      return total + (product.price * product.quantity);
    }, 0);
  }
}

const actions = {
  addToCart({ state, commit }, product) {
    if (product.inventory > 0) {
      let productItem = state.addedList.find(item => item.id === product.id);
      if (productItem) {
        commit('increamentItemQuantity', productItem);
      } else {
        commit('pushItemToCart', product);
      }
      commit('products/decreamentInventory', product, { root: true });
    }
  }
}

const mutations = {
  // 增加购物车中同等商品的数量
  increamentItemQuantity(state, { id }) {
    let productItem = state.addedList.find(item => item.id === id);
    productItem.quantity ++;
  },
  // 将商品加入购物车
  pushItemToCart(state, { id }) {
    state.addedList.push({
      id,
      quantity: 1
    })
  },
  
}

export default {
  namespaced: true,
  state,
  getters,
  actions,
  mutations
}

store/index.js

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

Vue.use(Vuex);

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

main.js

import Vue from "vue";
import App from "@/components/App.vue";
import store from "@/store";

Vue.config.productionTip = false;

new Vue({
  store,
  render: h => h(App)
}).$mount("#app");

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值