1. 状态系统架构设计思路
- 划分不同的store:
- 商品列表store:使用
writable
来存储购物车中的商品列表。每个商品对象包含商品ID、名称、价格、数量等信息。这样可以方便地对购物车中的商品进行增删改查操作。
- 总价store:通过
derived
从商品列表store派生而来。每当商品列表发生变化(添加、删除商品或修改商品数量)时,重新计算总价。这样可以确保总价始终与购物车中的商品状态保持一致,同时避免重复计算,提高效率。
- 商品数量store:同样使用
derived
从商品列表store派生,用于快速获取购物车中商品的总数量。
- 处理数据的同步与异步操作:
- 同步操作:添加商品到购物车、从购物车删除商品、修改商品数量等操作都是同步的。直接修改商品列表store即可,这些修改会立即反映到依赖它的派生store(如总价store、商品数量store)中。
- 异步操作:例如从服务器加载购物车初始数据,或者将购物车数据保存到服务器。在加载数据时,可以先显示加载状态,待数据加载完成后更新商品列表store。保存数据时,可以在保存成功后更新本地的商品列表store以保持一致性。使用
async/await
来处理异步操作,确保代码的可读性和顺序性。
- 确保系统的可维护性和扩展性:
- 模块化:将不同功能的逻辑封装成独立的模块,例如商品操作模块、数据请求模块等。每个模块负责自己的功能,降低模块之间的耦合度。
- 清晰的接口:为每个store和模块定义清晰的接口,其他部分通过接口来访问和操作数据,这样即使内部实现发生变化,也不会影响到其他部分。
- 使用类型声明:在Svelte中使用TypeScript,为store的数据结构和函数参数、返回值添加类型声明,提高代码的可维护性和可读性,同时在开发过程中可以利用类型检查发现潜在的错误。
2. 关键部分代码示例
<script lang="ts">
import { writable, derived } from'svelte/store';
// 商品列表store
type Product = {
id: number;
name: string;
price: number;
quantity: number;
};
const cartProducts = writable<Product[]>([]);
// 总价store
const totalPrice = derived(cartProducts, ($cartProducts) => {
return $cartProducts.reduce((acc, product) => acc + product.price * product.quantity, 0);
});
// 商品数量store
const totalQuantity = derived(cartProducts, ($cartProducts) => {
return $cartProducts.reduce((acc, product) => acc + product.quantity, 0);
});
// 同步操作:添加商品到购物车
const addProductToCart = (product: Product) => {
cartProducts.update((products) => {
const existingProduct = products.find(p => p.id === product.id);
if (existingProduct) {
existingProduct.quantity++;
return products;
} else {
return [...products, { ...product, quantity: 1 }];
}
});
};
// 异步操作:从服务器加载购物车数据
const loadCartData = async () => {
try {
const response = await fetch('/api/cart');
const data: Product[] = await response.json();
cartProducts.set(data);
} catch (error) {
console.error('Error loading cart data:', error);
}
};
// 异步操作:将购物车数据保存到服务器
const saveCartData = async () => {
try {
const response = await fetch('/api/cart', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify($cartProducts)
});
if (!response.ok) {
throw new Error('Failed to save cart data');
}
} catch (error) {
console.error('Error saving cart data:', error);
}
};
</script>
{#if $totalQuantity === 0}
<p>购物车为空</p>
{:else}
<p>购物车商品数量: {$totalQuantity}</p>
<p>购物车总价: {$totalPrice}</p>
{/if}
<button on:click={loadCartData}>加载购物车数据</button>
<button on:click={saveCartData}>保存购物车数据</button>