1. useStore结构设计
- 购物车状态结构:使用一个数组来存储购物车中的商品项。每个商品项是一个对象,包含商品名称、价格、数量等信息。例如:
import { useStore } from '@builder.io/qwik';
const useCartStore = () => {
const cart = useStore<Array<{
name: string;
price: number;
quantity: number;
}>>([]);
return cart;
};
- 持久化存储:可以利用浏览器的本地存储(localStorage)来实现状态的持久化。在初始化
useStore
时,尝试从本地存储中读取购物车数据,并在状态变化时更新本地存储。
import { useStore } from '@builder.io/qwik';
const useCartStore = () => {
const cart = useStore<Array<{
name: string;
price: number;
quantity: number;
}>>(() => {
const storedCart = localStorage.getItem('cart');
return storedCart ? JSON.parse(storedCart) : [];
});
cart.$onChange(() => {
localStorage.setItem('cart', JSON.stringify(cart));
});
return cart;
};
2. 操作处理
- 添加商品:向购物车数组中添加新的商品项对象。如果商品已存在,则增加其数量。
const addItemToCart = (name: string, price: number) => {
const cart = useCartStore();
const existingItem = cart.find(item => item.name === name);
if (existingItem) {
existingItem.quantity++;
} else {
cart.push({ name, price, quantity: 1 });
}
};
- 删除商品:从购物车数组中移除指定名称的商品项。
const removeItemFromCart = (name: string) => {
const cart = useCartStore();
const newCart = cart.filter(item => item.name!== name);
cart.length = 0;
newCart.forEach(item => cart.push(item));
};
- 修改数量:找到指定名称的商品项,并更新其数量。
const updateItemQuantity = (name: string, newQuantity: number) => {
const cart = useCartStore();
const item = cart.find(item => item.name === name);
if (item) {
item.quantity = newQuantity;
}
};
3. 保证状态一致性和持久化
- 页面刷新:由于使用了本地存储,在页面刷新时,
useStore
会从本地存储中读取数据进行初始化,保证购物车状态不变。
- 导航切换:Qwik的
useStore
本身是基于组件树的状态管理,导航切换时,只要组件树中使用了该useStore
,状态会保持一致。同时,本地存储的持久化也确保了即使在不同页面间切换,购物车状态依然存在。
4. 性能问题及解决方案
- 性能问题
- 频繁读写本地存储:每次状态变化都更新本地存储可能会导致性能问题,特别是在频繁操作购物车时。
- 渲染性能:如果购物车数据量较大,每次状态变化可能会导致不必要的组件重新渲染。
- 解决方案
- 批量更新本地存储:可以使用防抖(debounce)或节流(throttle)技术,减少本地存储的写入频率。例如,使用
lodash
的debounce
函数:
import { useStore } from '@builder.io/qwik';
import { debounce } from 'lodash';
const useCartStore = () => {
const cart = useStore<Array<{
name: string;
price: number;
quantity: number;
}>>(() => {
const storedCart = localStorage.getItem('cart');
return storedCart? JSON.parse(storedCart) : [];
});
const updateLocalStorage = debounce(() => {
localStorage.setItem('cart', JSON.stringify(cart));
}, 300);
cart.$onChange(() => {
updateLocalStorage();
});
return cart;
};
- **优化组件渲染**:使用Qwik的细粒度更新机制,通过`$key`等属性标记来控制组件的更新范围,避免不必要的重新渲染。例如,在展示购物车商品列表的组件中,为每个商品项添加`$key`:
{cart.map(item => (
<div key={item.name} $key={item.name}>
<p>{item.name}</p>
<p>Price: {item.price}</p>
<p>Quantity: {item.quantity}</p>
</div>
))}