Vue3组合式API实战:电商购物车组件全攻略

Vue3组合式API实战:从零构建可复用的电商购物车组件

Vue3的组合式API(Composition API)为开发者提供了一种更灵活、更可复用的代码组织方式。今天,我们将通过实战案例,一步步构建一个功能完善且高度可复用的电商购物车组件。无论你是Vue3新手还是有一定经验的开发者,这篇文章都能帮助你理解如何利用组合式API的优势来解决实际问题。

为什么选择组合式API?

在开始之前,让我们先简单了解一下为什么组合式API如此受欢迎。相比于Vue2的选项式API,组合式API的主要优势在于:

  • 更好的逻辑复用:通过将相关逻辑抽取到组合式函数中,可以在不同组件间轻松复用
  • 更灵活的组织方式:可以按功能而非选项(data、methods、computed等)来组织代码
  • 更好的TypeScript支持:类型推导更加直观,更容易编写类型安全的代码
  • 更小的打包体积:按需引入,有助于优化应用性能

第一步:规划购物车组件的功能

在开始编码前,我们先明确购物车组件需要实现的功能:

  • 展示商品列表,包括商品名称、单价、数量和总价
  • 支持修改商品数量(增加、减少、手动输入)
  • 支持删除商品
  • 计算购物车总金额
  • 提供清空购物车功能
  • 响应式更新,当数据变化时自动重新渲染

第二步:创建基础组件结构

我们先创建一个基础的组件结构。Vue3的组件仍然是单文件组件(SFC)的形式,但我们可以使用组合式API来编写逻辑部分。

“`html

购物车

购物车是空的,快去添加商品吧!
{{ item.name }}
¥{{ item.price }}


小计: ¥{{ calculateItemTotal(item) }}

总计: ¥{{ totalPrice }}

“`

第三步:使用组合式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的核心优势在于逻辑的复用和组织,合理利用它可以让你的代码更加优雅和高效。

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
none
暂无评论...