Vue3组合式API实战:从零构建可复用的电商购物车组件
Vue3的组合式API(Composition API)为开发者提供了一种更灵活、更可复用的代码组织方式。今天,我们将通过实战案例,一步步构建一个功能完善且高度可复用的电商购物车组件。无论你是Vue3新手还是有一定经验的开发者,这篇文章都能帮助你理解如何利用组合式API的优势来解决实际问题。
为什么选择组合式API?
在开始之前,让我们先简单了解一下为什么组合式API如此受欢迎。相比于Vue2的选项式API,组合式API的主要优势在于:
- 更好的逻辑复用:通过将相关逻辑抽取到组合式函数中,可以在不同组件间轻松复用
- 更灵活的组织方式:可以按功能而非选项(data、methods、computed等)来组织代码
- 更好的TypeScript支持:类型推导更加直观,更容易编写类型安全的代码
- 更小的打包体积:按需引入,有助于优化应用性能
第一步:规划购物车组件的功能
在开始编码前,我们先明确购物车组件需要实现的功能:
- 展示商品列表,包括商品名称、单价、数量和总价
- 支持修改商品数量(增加、减少、手动输入)
- 支持删除商品
- 计算购物车总金额
- 提供清空购物车功能
- 响应式更新,当数据变化时自动重新渲染
第二步:创建基础组件结构
我们先创建一个基础的组件结构。Vue3的组件仍然是单文件组件(SFC)的形式,但我们可以使用组合式API来编写逻辑部分。
“`html
购物车
¥{{ item.price }}
“`
第三步:使用组合式API实现逻辑
现在我们来编写组件的逻辑部分。我们将使用Vue3的“语法,这是组合式API的推荐写法。
“`html
import { ref, computed } from \’vue\’;
// 定义商品接口
interface CartItem {
id: number;
name: string;
price: number;
quantity: number;
}
// 模拟从API获取的购物车数据
const initialCartItems = [
{ id: 1, name: \’Vue3实战指南\’, price: 89, quantity: 1 },
{ id: 2, name: \’JavaScript高级程序设计\’, price: 129, quantity: 2 },
{ id: 3, name: \’CSS揭秘\’, price: 79, quantity: 1 }
];
// 响应式数据
const cartItems = ref(initialCartItems);
// 计算属性:购物车总金额
const totalPrice = computed(() => {
return cartItems.value.reduce((total, item) => {
return total + item.price * item.quantity;
}, 0);
});
// 方法:增加商品数量
function increaseQuantity(item: CartItem) {
item.quantity++;
}
// 方法:减少商品数量
function decreaseQuantity(item: CartItem) {
if (item.quantity > 1) {
item.quantity–;
}
}
// 方法:更新商品数量
function updateQuantity(item: CartItem) {
if (item.quantity i.id === item.id);
if (index !== -1) {
cartItems.value.splice(index, 1);
}
}
// 方法:清空购物车
function clearCart() {
cartItems.value = [];
}
// 方法:计算单个商品总价
function calculateItemTotal(item: CartItem) {
return item.price * item.quantity;
}
“`
第四步:添加样式和交互优化
一个良好的用户体验离不开合适的样式和交互细节。我们来添加一些CSS样式:
“`html
.shopping-cart {
max-width: 600px;
margin: 0 auto;
padding: 20px;
border: 1px solid #eee;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.empty-cart {
text-align: center;
padding: 40px;
color: #999;
}
.cart-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px;
border-bottom: 1px solid #eee;
}
.item-info {
display: flex;
flex-direction: column;
}
.item-name {
font-size: 16px;
font-weight: bold;
}
.item-price {
color: #666;
margin-top: 5px;
}
.item-controls {
display: flex;
align-items: center;
gap: 10px;
}
.item-controls button {
width: 30px;
height: 30px;
border: 1px solid #ddd;
background: white;
border-radius: 4px;
cursor: pointer;
}
.item-controls input {
width: 50px;
text-align: center;
border: 1px solid #ddd;
border-radius: 4px;
padding: 5px;
}
.remove-btn {
color: #f56c6c;
border: none;
background: none;
cursor: pointer;
margin-left: 10px;
}
.item-total {
font-weight: bold;
color: #333;
}
.cart-summary {
margin-top: 20px;
padding-top: 20px;
border-top: 2px solid #eee;
display: flex;
justify-content: space-between;
align-items: center;
}
.total-price {
font-size: 18px;
font-weight: bold;
}
.clear-btn {
background: #f56c6c;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
}
.clear-btn:hover {
background: #f78989;
}
“`
第五步:提取可复用逻辑
组合式API的一大优势是逻辑复用。我们可以将购物车相关的逻辑提取到一个组合式函数中,这样其他组件也可以使用相同的功能。
创建一个`useCart.ts`文件:
“`typescript
import { ref, computed } from \’vue\’;
interface CartItem {
id: number;
name: string;
price: number;
quantity: number;
}
export function useCart(initialItems: CartItem[]) {
const cartItems = ref(initialItems);
const totalPrice = computed(() => {
return cartItems.value.reduce((total, item) => {
return total + item.price * item.quantity;
}, 0);
});
function increaseQuantity(item: CartItem) {
item.quantity++;
}
function decreaseQuantity(item: CartItem) {
if (item.quantity > 1) {
item.quantity–;
}
}
function updateQuantity(item: CartItem) {
if (item.quantity i.id === item.id);
if (index !== -1) {
cartItems.value.splice(index, 1);
}
}
function clearCart() {
cartItems.value = [];
}
function calculateItemTotal(item: CartItem) {
return item.price * item.quantity;
}
return {
cartItems,
totalPrice,
increaseQuantity,
decreaseQuantity,
updateQuantity,
removeItem,
clearCart,
calculateItemTotal
};
}
“`
然后修改我们的购物车组件,使用这个组合式函数:
“`html
import { useCart } from \’./useCart\’;
// 使用组合式函数
const {
cartItems,
totalPrice,
increaseQuantity,
decreaseQuantity,
updateQuantity,
removeItem,
clearCart,
calculateItemTotal
} = useCart([
{ id: 1, name: \’Vue3实战指南\’, price: 89, quantity: 1 },
{ id: 2, name: \’JavaScript高级程序设计\’, price: 129, quantity: 2 },
{ id: 3, name: \’CSS揭秘\’, price: 79, quantity: 1 }
]);
“`
第六步:处理更复杂的场景
在实际项目中,购物车通常需要与后端API交互。我们可以进一步扩展我们的组合式函数,添加异步操作:
“`typescript
import { ref, computed } from \’vue\’;
interface CartItem {
id: number;
name: string;
price: number;
quantity: number;
}
export function useCart(initialItems: CartItem[]) {
const cartItems = ref(initialItems);
const loading = ref(false);
const totalPrice = computed(() => {
return cartItems.value.reduce((total, item) => {
return total + item.price * item.quantity;
}, 0);
});
async function syncWithBackend() {
loading.value = true;
try {
// 这里应该是实际的API调用
// const response = await api.updateCart(cartItems.value);
console.log(\’同步购物车数据到后端\’);
await new Promise(resolve => setTimeout(resolve, 500));
} catch (error) {
console.error(\’同步购物车失败:\’, error);
} finally {
loading.value = false;
}
}
function increaseQuantity(item: CartItem) {
item.quantity++;
syncWithBackend();
}
function decreaseQuantity(item: CartItem) {
if (item.quantity > 1) {
item.quantity–;
syncWithBackend();
}
}
function updateQuantity(item: CartItem) {
if (item.quantity i.id === item.id);
if (index !== -1) {
cartItems.value.splice(index, 1);
syncWithBackend();
}
}
function clearCart() {
cartItems.value = [];
syncWithBackend();
}
function calculateItemTotal(item: CartItem) {
return item.price * item.quantity;
}
return {
cartItems,
totalPrice,
loading,
increaseQuantity,
decreaseQuantity,
updateQuantity,
removeItem,
clearCart,
calculateItemTotal
};
}
“`
总结
通过这个实战案例,我们深入了解了Vue3组合式API的强大之处。从构建基础组件到提取可复用逻辑,再到处理更复杂的异步场景,组合式API都展现出了其灵活性和可维护性。
关键要点回顾:
- 组合式API按功能而非选项组织代码,使逻辑更清晰
- 通过组合式函数实现逻辑复用,减少重复代码
- 计算属性可以自动追踪依赖,实现响应式更新
- 可以轻松集成TypeScript,提高代码健壮性
- 适合处理复杂状态管理和异步操作
希望这个购物车组件的构建过程能帮助你更好地理解Vue3组合式API的实战应用。在实际项目中,你还可以根据具体需求进一步扩展功能,比如添加商品选择、批量操作、优惠券等。记住,组合式API的核心优势在于逻辑的复用和组织,合理利用它可以让你的代码更加优雅和高效。
