文档目录
组件体系设计

简介

本技术文档围绕 DouPHP 小程序的组件体系进行系统化说明,聚焦于“基础组件、业务组件、通用组件”的分类与职责边界,阐述组件接口定义、属性配置、事件绑定、插槽使用等开发规范;解释组件复用与扩展机制(继承、组合、插件化);并给出状态管理与数据流设计(props 传递、事件冒泡、全局状态同步)以及最佳实践与设计模式。内容基于仓库中 miniprogram/default 的实际实现进行提炼与总结。

项目结构

小程序采用“多主题/多实例”组织方式,default 与 company 两套独立的小程序工程共享相似结构。以 default 为例:

  • 入口与全局:app.ts、app.json、app.wxss
  • 页面:pages/*
  • 组件:components/*(如 navbar、mp-html)
  • 状态管理:stores/*(auth、cart、common 等)
  • 服务层:services/*(http、upload、lang 等)
  • 工具与类型:utils/、types/
graph TB
A["小程序入口<br/>app.ts"] --> B["应用配置<br/>app.json"]
A --> C["全局状态引导<br/>stores/index.ts"]
C --> D["认证状态<br/>stores/auth.ts"]
C --> E["购物车状态<br/>stores/cart.ts"]
A --> F["全局拦截与错误处理<br/>services/http.js(被引用)"]
B --> G["全局组件注册<br/>usingComponents: navbar"]
G --> H["导航栏组件<br/>components/navbar/*"]

核心组件

  • 基础组件
    • 导航栏组件(navbar):提供标题、背景色、透明度、返回/首页行为、左右插槽、调试入口等能力,适配不同设备状态栏高度与导航栏高度。
    • HTML 渲染组件(mp-html):用于富文本渲染(具体实现位于 components/mp-html)。
  • 业务组件
    • 当前仓库未直接暴露业务级组件,业务逻辑主要由页面与 stores/services 协作完成。
  • 通用组件
    • 导航栏同时承担通用 UI 能力,可跨页面复用,具备主题化与可插拔插槽。

架构总览

小程序采用“组件 + 状态管理 + 服务层”的分层架构:

  • 组件层:负责 UI 展示与交互(如 navbar),通过 properties 接收参数,通过 methods 触发事件或调用工具方法。
  • 状态层:使用 MobX 风格的 stores(authStore、cartStore、commonStore)集中管理登录态、购物车数量等全局状态,并在 app 启动时 hydrate/restore。
  • 服务层:封装网络请求、上传、语言等能力,统一错误处理与鉴权。
sequenceDiagram
participant App as "App(app.ts)"
participant Stores as "Stores(stores/index.ts)"
participant Auth as "Auth Store(auth.ts)"
participant Cart as "Cart Store(cart.ts)"
participant HTTP as "HTTP Service(services/http.js)"
participant Nav as "Navbar Component(navbar.ts/wxml)"
App->>App : onLaunch()
App->>Stores : bootstrapStores()
Stores->>Auth : hydrate()
Stores->>Auth : restore()
Auth->>HTTP : GET /user/index
HTTP-->>Auth : 登录态 flags
Stores->>Cart : refresh()
Cart->>HTTP : GET /order/cart_number
HTTP-->>Cart : 购物车数量
App->>Nav : 页面引入 navbar 组件
Nav->>Nav : 读取 globalData 高度信息

详细组件分析

导航栏组件(navbar)

  • 角色定位:基础/通用组件,提供统一的导航体验与可定制插槽。
  • 属性配置(properties)
    • title:标题文本,支持 observer 自动转换为字符串。
    • backgroundColor/titleColor:样式主题控制。
    • scrollOpacity:滚动透明度,控制背景与标题的视觉层级。
    • url:自定义返回目标 URL,为空则默认返回上一页。
    • showMenu:是否显示菜单按钮(返回/首页)。
  • 插槽使用(slots)
    • left/right:左侧/右侧自定义区域。
    • center:中心区域,未传入时使用 title 回退。
  • 事件与方法
    • goBack:根据 url 决定跳转或返回。
    • goHome:跳转到首页 tab。
    • openDebug:进入调试页(受环境与服务器开关双门控)。
  • 生命周期与数据
    • lifetimes.attached:初始化调试入口可见性。
    • data:从 app.globalData 读取状态栏/导航栏高度等信息,确保布局正确。
flowchart TD
Start(["组件挂载"]) --> ReadProps["读取 properties<br/>title/backgroundColor/scrollOpacity/url/showMenu"]
ReadProps --> Render["渲染 wxml<br/>背景层/标题/插槽"]
Render --> UserAction{"用户操作?"}
UserAction --> |点击返回| CheckUrl{"url 是否为空?"}
CheckUrl --> |是| GoBack["wx.navigateBack()"]
CheckUrl --> |否| GoTo["douPageTo(url)"]
UserAction --> |点击首页| SwitchTab["wx.switchTab('/pages/index/index')"]
UserAction --> |点击调试点| OpenDebug["wx.navigateTo('/pages/debug/debug')"]
GoBack --> End(["结束"])
GoTo --> End
SwitchTab --> End
OpenDebug --> End

全局状态管理(stores)

  • 启动流程(bootstrapStores)
    • 先 hydrate:从 storage 恢复本地状态(登录态、通用信息等)。
    • 再 restore:刷新服务端状态(登录态 flags、购物车数量)。
    • 绑定购物车角标:通过 autorun 监听 cartStore.badge,驱动 tabBar 角标更新。
  • 认证状态(authStore)
    • 字段:api_token、user_id、loginEd、is_login、is_vip、is_work、is_distribution。
    • 能力:hydrate/restore/ensureLogin/login/logout。
    • 降级策略:当 commonStore.features.user === false 时,不发起请求,保持空 flags。
  • 购物车状态(cartStore)
    • 字段:number(数量),badge(计算属性,0 显示空串,>99 显示 '99+')。
    • 能力:refresh/reset。
    • 降级策略:当 order 模块未启用或未登录时,静默返回 0,不发请求。
classDiagram
class AuthStore {
+string api_token
+string user_id
+boolean loginEd
+boolean is_login
+boolean is_vip
+boolean is_work
+boolean is_distribution
+hydrate() void
+applyAuthFlags(flags) void
+restore() Promise~void~
+ensureLogin(redirectUrl) Promise~boolean~
+login(payload) void
+logout() void
}
class CartStore {
+number number
+string badge
+refresh() Promise~void~
+reset() void
}
class Bootstrap {
+bootstrapStores() void
}
Bootstrap --> AuthStore : "hydrate/restore"
Bootstrap --> CartStore : "refresh/badge 绑定"

组件复用与扩展机制

  • 组合模式
    • 通过插槽(left/right/center)将复杂布局拆解为可组合的子区域,页面按需填充。
    • 通过 properties 注入主题与行为(颜色、透明度、URL、菜单显隐)。
  • 继承模式
    • 当前 navbar 未显式继承其他组件;可在未来通过基类或 mixin 抽象公共行为(如高度计算、调试入口)。
  • 插件机制
    • 通过 services/http.js 的统一拦截器实现鉴权失败时的全局登出与路由重定向,属于“横切关注点”的插件化扩展。
    • 通过 utils/env 与 site.ts 的双门控(客户端环境 + 服务端开关)控制调试入口可见性,体现可扩展的行为开关。

状态管理与数据流设计

  • Props 传递
    • 组件通过 properties 接收父级配置(如 title、backgroundColor、scrollOpacity、url、showMenu)。
  • 事件冒泡
    • 组件内部方法(goBack/goHome/openDebug)通过 wx API 执行导航或打开调试页,避免向父级冒泡过多事件,降低耦合。
  • 全局状态同步
    • 通过 stores/index.ts 在 app.onLaunch 时统一 hydrate/restore,保证首屏快速可用与数据一致性。
    • authStore 与 cartStore 分别维护登录态与购物车数量,并通过 autorun 驱动 tabBar 角标。

组件开发规范与最佳实践

  • 接口定义
    • 明确 properties 的类型与默认值,必要时使用 observer 做数据归一化(如 title 转字符串)。
  • 属性配置
    • 将样式与行为解耦(如 backgroundColor/titleColor/scrollOpacity),便于主题化与动态调整。
  • 事件绑定
    • 组件内部封装导航逻辑(goBack/goHome),对外暴露简洁方法,减少页面侧重复代码。
  • 插槽使用
    • 提供 left/right/center 插槽,满足多样化布局需求;未传入 center 时回退到 title,提升易用性。
  • 复用与扩展
    • 通过组合模式拆分布局,通过插件机制注入横切能力(鉴权、调试入口)。
  • 状态管理
    • 使用 stores 管理全局状态,避免散落的 globalData 与 storage 读写;对可选模块进行降级处理,保证稳定性。
  • 性能优化
    • 首屏 hydrate 后 restore,减少白屏时间;购物车角标通过 autorun 单向绑定,避免频繁 setTabBarBadge。

依赖关系分析

  • 组件依赖
    • navbar 依赖 utils/env、utils/ui 与 app.globalData 的高度信息。
  • 状态依赖
    • stores/index.ts 依赖 authStore、cartStore、commonStore,并绑定购物车角标。
    • authStore 依赖 http、route、promotion、commonStore。
    • cartStore 依赖 http、route、commonStore。
  • 外部集成
    • 通过 app.json 的 usingComponents 全局注册 navbar,供任意页面直接使用。
graph LR
Navbar["navbar.ts/wxml"] --> Env["utils/env.ts"]
Navbar --> UI["utils/ui.ts"]
Navbar --> Global["app.globalData"]
Index["stores/index.ts"] --> Auth["stores/auth.ts"]
Index --> Cart["stores/cart.ts"]
Auth --> HTTP["services/http.js"]
Auth --> Route["utils/route.ts"]
Auth --> Common["stores/common.ts"]
Cart --> HTTP
Cart --> Route
Cart --> Common
App["app.ts"] --> Index
AppJSON["app.json"] --> Navbar

性能考量

  • 首屏加载
    • 通过 hydrate 从 storage 恢复状态,实现秒开;随后异步 restore 刷新服务端数据,避免阻塞首屏。
  • 状态更新
    • 购物车角标通过 autorun 单向绑定,仅在状态变化时更新,减少不必要的 UI 刷新。
  • 降级策略
    • 对可选模块(user/order)进行特性开关判断,未启用时短路请求,降低无效网络开销。
  • 错误处理
    • 全局 onError/onUnhandledRejection 捕获异常,调试期弹窗提示,生产环境仅记录日志,避免崩溃。

故障排查指南

  • 常见问题
    • 登录后仍提示未登录:检查 authStore.restore 的网络响应与 UNAUTHORIZED 处理逻辑。
    • 购物车角标不更新:确认 cartStore.refresh 是否被调用,以及 autorun 绑定是否生效。
    • 导航栏高度异常:检查 app.globalData 中的 statusBarHeight/navigationBarHeight 是否正确设置。
  • 调试手段
    • 开启 vConsole:非正式版自动启用,便于查看控制台输出。
    • 调试入口:在双门控条件下显示调试圆点,进入调试页查看运行信息。

结论

DouPHP 小程序的组件体系以“组件 + 状态管理 + 服务层”为核心,通过清晰的职责划分与模块化设计,实现了高内聚、低耦合的可复用 UI 与稳定的全局状态管理。导航栏组件作为基础/通用组件,提供了丰富的插槽与主题化能力;stores 通过 hydrate/restore 保障首屏性能与数据一致性;服务层统一处理鉴权与错误。遵循本文的开发规范与最佳实践,可进一步提升组件的可维护性与扩展性。

附录

  • 组件注册
    • 在 app.json 的 usingComponents 中全局注册 navbar,便于任意页面直接使用。
  • 入口与配置
    • app.ts 负责应用启动、全局错误处理、推广解析与自动更新;app.json 定义页面路由、窗口样式与 tabBar。
添加日期:2026-10-05