文档目录
页面通信模式

简介

本技术文档围绕 DouPHP 小程序的页面通信模式,系统梳理并说明以下能力:

  • 页面栈导航传参与跳转策略
  • 全局状态共享(基于 MobX 的 Store)
  • 事件总线与跨页通知(通过 Store 响应式更新驱动)
  • 存储机制(本地持久化、启动时秒开、网络刷新)
  • 页面状态同步机制(实时数据同步、冲突解决、版本控制)
  • 跨页面数据共享最佳实践(一致性、性能、安全)
  • 复杂交互场景方案(表单回填、列表筛选、购物车同步等)

目标是为开发者提供一套可落地的通信范式与实现参考,帮助在不同业务场景中选择合适的通信方式。

项目结构

DouPHP 小程序采用“应用入口 + 统一 HTTP 层 + 模块化 Store + 工具库”的分层组织:

  • 应用入口负责初始化全局环境、错误处理、自动更新、推广解析与 Store 引导
  • HTTP 层封装请求信封、缓存、去重、拦截器与调试钩子
  • Store 层以 MobX 管理登录态、公共数据、购物车等业务状态,并通过 autorun 驱动 UI 更新
  • 工具库提供命名路由生成、页面跳转决策、UI 辅助等通用能力
graph TB
App["应用入口 app.ts"] --> StoresIndex["Store 聚合 stores/index.ts"]
StoresIndex --> AuthStore["登录态 stores/auth.ts"]
StoresIndex --> CommonStore["公共数据 stores/common.ts"]
StoresIndex --> CartStore["购物车 stores/cart.ts"]
App --> Http["HTTP 服务 services/http.ts"]
StoresIndex --> Route["命名路由 utils/route.ts"]
StoresIndex --> Ui["页面跳转 utils/ui.ts"]

核心组件

  • 应用入口(App):注册全局错误钩子、自动更新、推广参数解析、窗口尺寸计算;在 onLaunch 中引导 Store 初始化与预热。
  • HTTP 层:统一信封解析、鉴权头注入、请求/成功/错误拦截器、内存缓存与请求去重、调试增强。
  • Store 体系:
    • commonStore:种子数据秒开、网络刷新、features 下发、语言包合并与持久化
    • authStore:登录态持久化、模块降级、ensureLogin 统一鉴权跳转
    • cartStore:购物车数量与角标联动、模块降级与未登录短路
  • 工具库:
    • route:命名路由生成,兼容 rewrite 开关,统一 URL 形态
    • ui:智能页面跳转(回退/switchTab/redirectTo),当前页 URL 构造

架构总览

下图展示了小程序启动到页面通信的关键路径:应用启动后先 hydrate 本地数据,再刷新网络数据;Store 间通过响应式绑定驱动 UI;页面间通过命名路由与工具函数进行导航与传参;HTTP 层为所有数据访问提供一致的信封与缓存语义。

sequenceDiagram
participant U as "用户"
participant A as "应用入口 app.ts"
participant SI as "Store 聚合 stores/index.ts"
participant CS as "公共数据 stores/common.ts"
participant AS as "登录态 stores/auth.ts"
participant CTS as "购物车 stores/cart.ts"
participant H as "HTTP 服务 services/http.ts"
participant R as "命名路由 utils/route.ts"
participant UI as "页面跳转 utils/ui.ts"
U->>A : 启动小程序
A->>SI : bootstrapStores()
SI->>CS : hydrate()
SI->>AS : hydrate()
SI->>CTS : bindCartBadge()
SI->>CS : refresh()
CS->>H : fetchBootstrap()
H-->>CS : 返回信封 data
CS->>CS : applyData() + 持久化
SI->>AS : restore()
AS->>R : route('user')
AS->>H : GET /user
H-->>AS : 返回信封 data
AS->>AS : applyAuthFlags()
SI->>CTS : refresh()
CTS->>R : route('order.cart')
CTS->>H : GET /order/cart
H-->>CTS : 返回信封 data
CTS->>CTS : number = cart_number
Note over CTS,UI : autorun 触发 wx.setTabBarBadge

详细组件分析

页面栈导航传参

  • 智能跳转策略:优先回退到已在页面栈的目标页;若目标是 tabBar 页则使用 switchTab;否则使用 redirectTo。
  • 当前页 URL 构造:读取当前 page.route 与 options 拼装成带参数的 URL,便于分享或记录。
  • 适用场景:
    • 列表到详情:传递 id、分类等参数
    • 搜索历史:将关键词写入 storage 并跳转到搜索结果页
    • 表单回填:从详情页回退时携带回填数据
flowchart TD
Start(["调用 douPageTo(url)"]) --> CheckStack{"目标是否在页面栈"}
CheckStack --> |是| Back["wx.navigateBack(delta)"]
CheckStack --> |否| IsTab{"是否 tabBar 页"}
IsTab --> |是| Switch["wx.switchTab({url})"]
IsTab --> |否| Redirect["wx.redirectTo({url})"]
Back --> End(["完成"])
Switch --> End
Redirect --> End

全局变量共享(Store 响应式)

  • 单一真相源:commonStore 作为站点信息、语言包、功能开关(features)、导航数据的唯一来源,支持 SWR 模式(Seed -> Hydrate -> Refresh)。
  • 登录态共享:authStore 维护 api_token、user_id、loginEd 及业务 flags(is_login、is_vip 等),并提供 ensureLogin 统一鉴权跳转。
  • 购物车共享:cartStore 暴露 number 与 badge 计算属性,配合 autorun 驱动 tabBar 角标。
  • 适用场景:
    • 多页面共享用户信息、站点配置、功能开关
    • 跨页面同步购物车数量与角标
    • 统一鉴权与降级(模块未启用时短路)
classDiagram
class CommonStore {
+site
+lang
+param
+nav_list
+features
+data
+version
+ready
+applyData(payload)
+hydrate()
+refresh()
}
class AuthStore {
+api_token
+user_id
+loginEd
+is_login
+is_vip
+is_work
+is_distribution
+hydrate()
+restore()
+ensureLogin(redirectUrl)
+login(payload)
+logout()
}
class CartStore {
+number
+badge
+refresh()
+reset()
}
CommonStore <.. AuthStore : "features 控制降级"
CommonStore <.. CartStore : "features 控制降级"

事件总线(基于 Store 的响应式通知)

  • 机制说明:通过 MobX 的 observable + autorun,当 Store 状态变化时自动触发副作用(如更新 tabBar 角标、刷新列表)。
  • 优势:解耦页面与数据源,避免手动派发/监听带来的耦合;天然支持批量更新与细粒度订阅。
  • 典型用法:
    • 购物车数量变化 -> 自动更新角标
    • 登录态变化 -> 自动切换展示内容或跳转登录页
    • features 变化 -> 动态启用/禁用模块相关页面

存储机制(本地持久化与启动秒开)

  • 种子数据:首帧即有文案与站点名,保证冷启动体验。
  • Hydrate:从 storage 恢复 commonStore、authStore 的状态,实现 0ms 冷启动。
  • Refresh:网络刷新后合并语言包与 features,并写回 storage 持久化。
  • 适用场景:
    • 首屏快速渲染
    • 离线可用(保留上次有效数据)
    • 跨会话保持登录态与偏好

页面状态同步机制

  • 实时数据同步:Store 的 autorun 与响应式更新确保 UI 与数据一致;HTTP 层的 dedupe 与 cache 减少重复请求。
  • 冲突解决:SWR 模式(Seed -> Hydrate -> Refresh)保证最终一致性;失败时保留已有数据不打断首屏。
  • 版本控制:commonStore.version 由后端下发,可用于前端缓存失效与灰度策略。
  • 适用场景:
    • 购物车数量与角标的实时同步
    • 登录态变化后的统一鉴权跳转
    • 功能开关变更后的模块级降级

跨页面数据共享最佳实践

  • 数据一致性:以 Store 为单一真相源,页面仅消费状态,不直接修改共享数据;通过 action 更新。
  • 性能考虑:GET 请求默认去重与内存缓存;按需 revalidate;避免频繁 setData 大对象。
  • 安全性保障:Authorization 头由 HTTP 层注入;UNAUTHORIZED 统一登出;敏感数据不落盘或加密存储(根据业务需求扩展)。
  • 适用场景:
    • 多页面共享用户信息与权限
    • 购物车跨页同步
    • 功能开关驱动的页面可见性

复杂页面交互场景解决方案

  • 表单回填:利用页面栈回退(navigateBack)携带参数,或使用 storage 暂存草稿,进入页面时 hydrate 并填充。
  • 列表筛选:将筛选条件存入 storage 或通过路由参数传递;列表页读取后发起请求,结果缓存并去重。
  • 购物车同步:cartStore.number 变化通过 autorun 更新角标;添加/删除商品后调用 refresh 拉取最新数量。
  • 推荐流程:扫码/分享进入 -> onLaunch 解析 user_sn -> 写入 storage -> 后续请求携带推广标识。

依赖关系分析

  • 应用入口依赖 Store 聚合与 HTTP 层;Store 聚合依赖各业务 Store;业务 Store 依赖 HTTP 层与命名路由;工具库被多处复用。
  • 潜在循环依赖:Store 之间通过 commonStore.features 进行降级判断,无直接循环引用。
  • 外部依赖:微信 API(wx.request、wx.getStorageSync 等)、MobX 响应式库。
graph LR
App["app.ts"] --> SI["stores/index.ts"]
SI --> CS["stores/common.ts"]
SI --> AS["stores/auth.ts"]
SI --> CTS["stores/cart.ts"]
CS --> H["services/http.ts"]
AS --> H
CTS --> H
AS --> R["utils/route.ts"]
CTS --> R
App --> UI["utils/ui.ts"]

性能考虑

  • 首屏优化:种子数据 + Hydrate 实现秒开;网络失败保留已有数据。
  • 请求优化:GET 去重与内存缓存;按需 revalidate;失败静默降级。
  • UI 更新:autorun 细粒度订阅,避免全量刷新;角标更新集中管理。
  • 建议:
    • 合理使用 cache/ttl/revalidate 控制缓存策略
    • 避免在高频回调中执行重计算或大量 setData
    • 对大对象使用分页与虚拟列表

故障排查指南

  • 统一错误处理:HTTP 层将网络异常、HTTP 非 2xx、业务码非 OK 统一为 ApiError;app 层 onError 捕获 JS 异常并在调试期弹窗。
  • 鉴权失败:UNAUTHORIZED 触发登出;authStore.restore 仅在 UNAUTHORIZED 时清空 is_login,其他错误保留登录态避免弱网假登出。
  • 调试增强:request_id 装饰错误消息;调试期弹出服务端异常堆栈并支持复制。
  • 建议:
    • 使用 getLastRequestId 关联前后端日志
    • 在开发环境开启 vConsole 与调试弹窗
    • 对关键路径增加埋点与错误上报

结论

DouPHP 小程序的页面通信以 Store 为核心,结合 HTTP 层与工具库,形成了一套高内聚、低耦合、可扩展的通信体系。通过 SWR 模式、响应式更新与统一错误处理,实现了高效、稳定、易维护的跨页面数据共享与状态同步。在实际项目中,应根据场景选择合适的通信方式:简单传参用页面栈导航,复杂状态用 Store,跨会话数据用存储,实时同步用响应式绑定。

附录

  • 命名路由:通过 route(name, params) 生成统一 URL,兼容 rewrite 开关与 query 拼接。
  • 页面跳转:douPageTo 智能决策回退/switchTab/redirectTo,适配模块化裁剪后的 tabBar。
  • 启动流程:onLaunch 解析推广参数、初始化 Store、计算窗口尺寸、自动更新。
添加日期:2026-10-05