实现一个简单的购物车:Vue3 状态管理的实战
在前端开发中,购物车是许多应用中的一个关键部分。随着Vue3的推出,我们可以利用其新特性,特别是组合式 API(setup 语法糖),来实现一个简单而实用的购物车功能。在这篇文章中,我们将逐步构建一个基本的购物车应用,并深入了解Vue3的状态管理如何工作。
项目结构
首先,我们创建一个新的Vue 3项目并设置项目结构。可以使用Vue CLI创建项目:
vue create shopping-cart
选择默认配置后,项目结构大致如下:
shopping-cart/
|-- src/
| |-- components/
| | |-- Cart.vue
| | |-- ProductList.vue
| |-- App.vue
| |-- main.js
|-- public/
在 src/components
目录下,我们将创建两个组件:Cart.vue
和 ProductList.vue
。
创建状态管理
为了管理购物车的状态,我们可以使用Vue 3提供的 reactive
和 ref
来创建一个简单的状态管理。我们将创建一个 useCart
钩子,负责购物车的所有状态和逻辑。
在 src
目录下创建一个新文件 useCart.js
:
// src/useCart.js
import { reactive, computed } from 'vue';
const state = reactive({
cart: []
});
const addToCart = (product) => {
const existingProduct = state.cart.find(item => item.id === product.id);
if (existingProduct) {
existingProduct.quantity += 1;
} else {
state.cart.push({ ...product, quantity: 1 });
}
};
const removeFromCart = (productId) => {
state.cart = state.cart.filter(item => item.id !== productId);
};
const totalItems = computed(() => {
return state.cart.reduce((total, item) => total + item.quantity, 0);
});
const totalPrice = computed(() => {
return state.cart.reduce((total, item) => total + item.price * item.quantity, 0).toFixed(2);
});
export default function useCart() {
return {
state,
addToCart,
removeFromCart,
totalItems,
totalPrice,
};
}
在这个 useCart.js
文件中,我们定义了一个 state
对象,其中包含购物车的商品。我们也定义了addToCart
和 removeFromCart
函数来添加和移除商品,以及计算总商品数量和总价格的计算属性。
创建产品列表组件
接下来,我们将创建一个 ProductList.vue
组件来展示可购买的商品,并实现添加到购物车的功能。
<!-- src/components/ProductList.vue -->
<template>
<div>
<h2>产品列表</h2>
<div class="product" v-for="product in products" :key="product.id">
<h3>{{ product.name }}</h3>
<p>价格: ${{ product.price.toFixed(2) }}</p>
<button @click="addToCart(product)">加入购物车</button>
</div>
</div>
</template>
<script>
import useCart from '../useCart';
export default {
setup() {
const { addToCart } = useCart();
const products = [
{ id: 1, name: '商品1', price: 29.99 },
{ id: 2, name: '商品2', price: 39.99 },
{ id: 3, name: '商品3', price: 49.99 },
];
return {
products,
addToCart,
};
}
}
</script>
<style scoped>
.product {
border: 1px solid #ccc;
padding: 10px;
margin: 10px 0;
}
</style>
在这个组件中,我们定义了一个简单的产品列表,通过 v-for
指令循环遍历所有商品,并为每个商品添加了一个“加入购物车”按钮。点击按钮时,调用 addToCart
方法将商品添加到购物车。
创建购物车组件
接下来,我们将创建 Cart.vue
组件来展示购物车中的商品并实现移除功能。
<!-- src/components/Cart.vue -->
<template>
<div>
<h2>购物车</h2>
<div v-if="cart.length === 0">购物车是空的</div>
<div v-else>
<ul>
<li v-for="item in cart" :key="item.id">
{{ item.name }} - {{ item.quantity }} x ${{ item.price.toFixed(2) }}
<button @click="removeFromCart(item.id)">移除</button>
</li>
</ul>
<p>总商品数: {{ totalItems }}</p>
<p>总价格: ${{ totalPrice }}</p>
</div>
</div>
</template>
<script>
import useCart from '../useCart';
export default {
setup() {
const { state, removeFromCart, totalItems, totalPrice } = useCart();
return {
cart: state.cart,
removeFromCart,
totalItems,
totalPrice,
};
}
}
</script>
<style scoped>
ul {
list-style-type: none;
padding: 0;
}
</style>
在这个组件中,我们从状态管理中获取购物车中的商品,并展示它们的名称、数量和价格。同时我们计算总商品数和总价格。如有需要,还可以通过“移除”按钮来移除购物车中的商品。
整合一切
最后,我们需要将这些组件整合到 App.vue
中:
<!-- src/App.vue -->
<template>
<div id="app">
<h1>简单购物车示例</h1>
<ProductList />
<Cart />
</div>
</template>
<script>
import ProductList from './components/ProductList.vue';
import Cart from './components/Cart.vue';
export default {
components: {
ProductList,
Cart,
},
}
</script>
<style>
#app {
max-width: 600px;
margin: auto;
}
</style>
在 App.vue
中,我们引入并使用 ProductList
和 Cart
组件,使我们的购物车应用可以正常运行。
总结
至此,我们已经利用Vue 3中的组合式 API 创建了一个简单的购物车应用。通过使用 reactive
和 computed
管理状态,我们能够高效并简洁地管理购物车的功能。
这个项目为你提供了一个基础,可以在此基础上扩展更多功能,例如用户认证、持久化购物车数据到本地存储等。