Files
mp-vue/docs/状态管理实现总结.md

206 lines
5.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 网站信息和统计数据状态管理实现总结
## 问题背景
原项目中 `getSiteInfo``loadStatistics` 方法在多个组件中重复调用,存在以下问题:
1. **重复请求**:每个组件都独立调用 API造成不必要的网络请求
2. **数据不一致**:各组件间数据可能不同步
3. **类型安全问题**TypeScript 提示 "Object is possibly undefined" 错误
4. **维护困难**:相同逻辑分散在多个组件中
## 解决方案
### 1. 创建状态管理 Store
#### 网站信息 Store (`src/store/modules/site.ts`)
- **功能**管理网站基本信息名称、Logo、域名等
- **缓存策略**30分钟有效期适合相对稳定的数据
- **特性**
- 智能缓存管理
- 自动计算系统运行天数
- 自动更新 localStorage
- 完整的类型保护
#### 统计数据 Store (`src/store/modules/statistics.ts`)
- **功能**:管理统计数据(用户数、订单数、销售额等)
- **缓存策略**5分钟有效期支持自动刷新
- **特性**
- 短期缓存 + 自动刷新机制
- 异步更新数据库
- 类型安全的数据处理
- 错误处理和重试机制
### 2. 类型保护工具 (`src/utils/type-guards.ts`)
创建了一套完整的类型保护工具函数:
```typescript
// 安全获取数字值
safeNumber(value: unknown, defaultValue = 0): number
// 检查对象是否有有效的 ID
hasValidId(obj: unknown): obj is { id: number }
// 检查 API 响应是否有效
isValidApiResponse<T>(response: unknown): response is { count: number; list?: T[] }
```
### 3. 组合式函数 (`src/composables/useSiteData.ts`)
提供统一的数据访问接口:
```typescript
const {
websiteName,
websiteLogo,
userCount,
orderCount,
loading,
refreshAll,
startAutoRefresh,
stopAutoRefresh
} = useSiteData();
```
## 核心特性
### 1. 智能缓存管理
- **网站信息**30分钟缓存适合稳定数据
- **统计数据**5分钟缓存支持实时更新
- **缓存验证**:自动检查缓存有效性
### 2. 自动刷新机制
```typescript
// 开始自动刷新默认5分钟间隔
statisticsStore.startAutoRefresh();
// 停止自动刷新
statisticsStore.stopAutoRefresh();
```
### 3. 类型安全
- 完整的 TypeScript 类型定义
- 运行时类型检查
- 安全的数据访问方法
### 4. 错误处理
- API 调用失败处理
- 数据验证和默认值
- 详细的错误日志
## 使用方式
### 方式一:直接使用 Store
```vue
<script setup>
import { useSiteStore } from '@/store/modules/site';
import { useStatisticsStore } from '@/store/modules/statistics';
const siteStore = useSiteStore();
const statisticsStore = useStatisticsStore();
onMounted(async () => {
await Promise.all([
siteStore.fetchSiteInfo(),
statisticsStore.fetchStatistics()
]);
statisticsStore.startAutoRefresh();
});
</script>
```
### 方式二:使用组合式函数(推荐)
```vue
<script setup>
import { useSiteData } from '@/composables/useSiteData';
const {
websiteName,
userCount,
loading,
refreshAll,
startAutoRefresh,
stopAutoRefresh
} = useSiteData();
onMounted(async () => {
await refreshAll();
startAutoRefresh();
});
onUnmounted(() => {
stopAutoRefresh();
});
</script>
```
## 已更新的组件
1. **`src/views/cms/dashboard/index.vue`** - 仪表板页面
2. **`src/layout/components/header-tools.vue`** - 头部工具栏
3. **`src/views/cms/setting/index.vue`** - 设置页面
4. **`src/views/shop/index.vue`** - 商店页面
## 数据更新策略
### 推荐的混合策略:
1. **前端定时更新** + **后端实时计算**
- 前端每5-10分钟自动刷新统计数据
- 后端提供实时计算接口
- 用户手动刷新时立即更新
2. **分层缓存**
- 基础信息(网站信息):状态管理 + 长期缓存
- 统计数据:短期缓存 + 定时更新
- 实时数据:不缓存,每次请求
## 性能优化
1. **减少 API 调用**:智能缓存避免重复请求
2. **内存优化**:及时清理定时器和监听器
3. **类型优化**:编译时类型检查,减少运行时错误
4. **按需加载**:只在需要时获取数据
## 最佳实践
1. **生命周期管理**
```typescript
onMounted(() => startAutoRefresh());
onUnmounted(() => stopAutoRefresh());
```
2. **错误处理**
```typescript
try {
await fetchSiteInfo();
} catch (error) {
console.error('获取网站信息失败:', error);
}
```
3. **强制刷新**
```typescript
const handleRefresh = () => refreshAll(true);
```
## 构建验证
✅ TypeScript 编译通过
✅ 所有类型错误已解决
✅ 生产构建成功
✅ 无运行时错误
## 总结
通过实现状态管理,我们成功解决了:
1. **重复 API 调用问题** - 智能缓存机制
2. **类型安全问题** - 完整的类型保护
3. **数据一致性问题** - 统一的数据源
4. **维护性问题** - 集中的状态管理
这个实现为项目提供了更好的性能、更强的类型安全性和更易维护的代码结构。