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

5.0 KiB
Raw Permalink Blame History

网站信息和统计数据状态管理实现总结

问题背景

原项目中 getSiteInfoloadStatistics 方法在多个组件中重复调用,存在以下问题:

  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)

创建了一套完整的类型保护工具函数:

// 安全获取数字值
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)

提供统一的数据访问接口:

const {
  websiteName,
  websiteLogo,
  userCount,
  orderCount,
  loading,
  refreshAll,
  startAutoRefresh,
  stopAutoRefresh
} = useSiteData();

核心特性

1. 智能缓存管理

  • 网站信息30分钟缓存适合稳定数据
  • 统计数据5分钟缓存支持实时更新
  • 缓存验证:自动检查缓存有效性

2. 自动刷新机制

// 开始自动刷新默认5分钟间隔
statisticsStore.startAutoRefresh();

// 停止自动刷新
statisticsStore.stopAutoRefresh();

3. 类型安全

  • 完整的 TypeScript 类型定义
  • 运行时类型检查
  • 安全的数据访问方法

4. 错误处理

  • API 调用失败处理
  • 数据验证和默认值
  • 详细的错误日志

使用方式

方式一:直接使用 Store

<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>

方式二:使用组合式函数(推荐)

<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. 生命周期管理

    onMounted(() => startAutoRefresh());
    onUnmounted(() => stopAutoRefresh());
    
  2. 错误处理

    try {
      await fetchSiteInfo();
    } catch (error) {
      console.error('获取网站信息失败:', error);
    }
    
  3. 强制刷新

    const handleRefresh = () => refreshAll(true);
    

构建验证

TypeScript 编译通过
所有类型错误已解决
生产构建成功
无运行时错误

总结

通过实现状态管理,我们成功解决了:

  1. 重复 API 调用问题 - 智能缓存机制
  2. 类型安全问题 - 完整的类型保护
  3. 数据一致性问题 - 统一的数据源
  4. 维护性问题 - 集中的状态管理

这个实现为项目提供了更好的性能、更强的类型安全性和更易维护的代码结构。