简介
本组件为 DouPHP 小程序的自定义导航栏,提供状态栏高度适配、胶囊按钮位置计算、返回/首页按钮、标题显示与滚动透明度控制、调试入口圆点等功能。通过全局 App 初始化设备信息,组件在运行时读取并渲染,保证在不同机型与微信版本下的一致体验。
项目结构
- 组件位于 miniprogram/default/components/navbar,包含逻辑、模板、样式与声明文件。
- 全局设备信息在 app.ts 中初始化,供组件消费。
- 页面跳转与工具函数封装在 utils/ui.ts,组件复用以实现统一的导航行为。
- 环境判断与调试开关在 utils/env.ts,用于控制调试入口的可见性。
graph TB
subgraph "小程序应用"
A["App 启动<br/>app.ts"]
end
subgraph "导航栏组件"
B["组件逻辑<br/>navbar.ts"]
C["组件模板<br/>navbar.wxml"]
D["组件样式<br/>navbar.wxss"]
end
subgraph "工具与环境"
E["UI 工具<br/>utils/ui.ts"]
F["环境与调试<br/>utils/env.ts"]
end
A --> B
B --> C
B --> D
B --> E
B --> F
图表来源
- app.ts:12-62
- navbar.ts:1-79
- navbar.wxml:1-39
- navbar.wxss:1-102
- ui.ts:30-47
- env.ts:12-37
章节来源
- app.ts:12-62
- navbar.ts:1-79
- navbar.wxml:1-39
- navbar.wxss:1-102
- ui.ts:30-47
- env.ts:12-37
核心组件
- 组件属性(properties)
- title:页面标题,支持任意类型,内部会转为字符串;为空时显示空串。
- backgroundColor:背景颜色,默认白色。
- titleColor:标题颜色,默认深灰。
- scrollOpacity:背景层透明度(0~1),同时影响默认标题透明度。
- url:点击返回时的目标 URL,留空则执行返回上一页。
- showMenu:是否显示左侧菜单(返回/首页)。
- 数据(data)
- statusBarHeight、navigationBarHeight、menuButtonHeight、navigationBarAndStatusBarHeight 等来自全局 globalData,用于精确占位与布局。
- debugDot:根据环境与服务器调试开关决定是否显示调试入口圆点。
- 生命周期
- attached:在组件挂载时根据环境与服务器调试开关设置 debugDot。
- 方法(methods)
- goBack:优先跳转到指定 url,否则返回上一页。
- goHome:跳转到首页 tabbar。
- openDebug:进入调试信息页(仅满足双门控条件时可见)。
章节来源
- navbar.ts:12-48
- navbar.ts:50-77
架构总览
导航栏由“全局设备信息 + 组件逻辑 + 模板 + 样式”构成。App 启动时采集系统状态栏高度、窗口高度、胶囊按钮尺寸,并计算导航栏高度与组合高度,写入 globalData。组件在渲染时读取这些值,完成状态栏占位、导航栏高度对齐、胶囊区域避让与居中标题定位。
sequenceDiagram
participant App as "App(app.ts)"
participant Nav as "导航栏(navbar.ts)"
participant UI as "UI工具(ui.ts)"
participant WX as "微信API"
App->>WX : 获取窗口与设备信息
App->>App : 计算导航栏高度与组合高度
Nav->>App : 读取globalData(状态栏/导航栏/胶囊高度)
Nav->>Nav : 渲染占位与布局
Nav->>UI : 调用douPageTo(url)或navigateBack()
UI->>WX : switchTab/redirectTo/navigateBack
图表来源
- app.ts:37-54
- navbar.ts:40-48
- ui.ts:30-47
详细组件分析
状态栏与导航栏高度适配
- 状态栏高度:从 wx.getWindowInfo().statusBarHeight 获取,作为顶部空白占位,避免内容被系统状态栏遮挡。
- 导航栏高度:优先通过 wx.getMenuButtonBoundingClientRect() 的 top 与 height 计算,回退到平台固定值(Android 与其他平台不同)。
- 组合高度:状态栏高度 + 导航栏高度,用于外层容器与底部占位,确保 fixed 定位的导航栏与页面内容不重叠。
flowchart TD
Start(["启动"]) --> GetWin["获取窗口信息"]
GetWin --> GetMenu["获取胶囊按钮边界"]
GetMenu --> Calc{"top/height 有效?"}
Calc --> |是| UseCalc["按公式计算导航栏高度"]
Calc --> |否| Fallback["按平台回退高度"]
UseCalc --> Combine["组合高度=状态栏+导航栏"]
Fallback --> Combine
Combine --> End(["写入globalData"])
图表来源
- app.ts:37-54
章节来源
- app.ts:37-54
胶囊按钮位置与居中标题
- 左侧菜单区域预留空间,避免与系统胶囊按钮重叠。
- 标题区域采用绝对定位,左右边距预留以避开胶囊区域,实现视觉居中。
- 当未传入 center 插槽时,默认标题跟随 scrollOpacity 变化透明度。
graph LR
L["左侧菜单区"] --> C["居中标题区"]
C --> R["右侧插槽区"]
C -.-> M["系统胶囊按钮(避让)"]
图表来源
- navbar.wxml:8-28
- navbar.wxss:16-55
章节来源
- navbar.wxml:8-28
- navbar.wxss:16-55
返回按钮处理逻辑
- 若属性 url 存在,则调用 douPageTo 进行智能跳转(已在当前栈则回退,tabBar 路径走 switchTab,否则 redirectTo)。
- 若 url 为空,直接返回上一页。
- 该逻辑统一了返回与跳转行为,减少页面间耦合。
sequenceDiagram
participant U as "用户"
participant N as "导航栏(navbar.ts)"
participant U2 as "UI工具(ui.ts)"
participant W as "微信API"
U->>N : 点击返回
alt 有url
N->>U2 : douPageTo(url)
U2->>W : switchTab/redirectTo/navigateBack
else 无url
N->>W : navigateBack()
end
图表来源
- navbar.ts:60-67
- ui.ts:30-47
章节来源
- navbar.ts:60-67
- ui.ts:30-47
事件回调机制
- 返回按钮点击:触发 goBack,依据 url 决定跳转或返回。
- 首页按钮点击:触发 goHome,切换到首页 tabBar。
- 调试入口圆点点击:触发 openDebug,进入调试页(仅在非正式版且服务端调试开启时显示)。
章节来源
- navbar.ts:59-77
- navbar.wxml:10-17
- navbar.wxml:36-38
样式定制与主题切换
- 背景色:通过 backgroundColor 属性覆盖。
- 标题色:通过 titleColor 属性覆盖。
- 滚动透明度:通过 scrollOpacity 控制背景层与默认标题透明度。
- 插槽扩展:left/right/center 插槽可完全替换默认内容,实现个性化布局。
- 主题切换:可在页面层动态修改属性值,或在组件外层包裹一层主题容器,结合 CSS 变量实现全局换肤(需自行扩展)。
章节来源
- navbar.ts:12-38
- navbar.wxml:3-27
- navbar.wxss:9-25
兼容性处理方案
- 设备差异:通过 wx.getMenuButtonBoundingClientRect 计算导航栏高度,并在无效时回退到平台常量,兼容不同机型。
- 基础库差异:环境检测函数在低版本基础库下回退读取 __wxConfig,保证 isDebugEnv 可用。
- 调试入口:仅在客户端非正式版且服务端调试开启时显示,避免生产环境泄露调试能力。
章节来源
- app.ts:37-54
- env.ts:12-37
- navbar.ts:50-56
依赖关系分析
- 组件依赖全局 globalData 中的设备信息,确保布局准确。
- 组件依赖 UI 工具进行统一的路由决策,降低业务页面复杂度。
- 组件依赖环境检测模块控制调试入口可见性。
graph LR
NAV["navbar.ts"] --> APP["app.ts(globalData)"]
NAV --> UI["ui.ts(douPageTo)"]
NAV --> ENV["env.ts(isDebugEnv/isServerDebug)"]
图表来源
- navbar.ts:1-79
- app.ts:12-62
- ui.ts:30-47
- env.ts:12-37
章节来源
- navbar.ts:1-79
- app.ts:12-62
- ui.ts:30-47
- env.ts:12-37
性能与优化
- 避免重复计算:设备信息在 App 启动时一次性计算并缓存至 globalData,组件直接读取,减少运行时开销。
- 最小化重排:使用固定高度与绝对定位布局,减少频繁 reflow。
- 按需渲染:调试入口圆点通过双门控隐藏,减少不必要的 DOM 与事件绑定。
- 路由优化:统一使用 douPageTo,自动识别 tabBar 与页面栈,避免错误跳转导致的额外刷新。
故障排查
- 标题被胶囊遮挡:检查 left/right 内边距与居中区域的左右边距是否足够,确保不被系统胶囊覆盖。
- 返回无效:确认 url 是否正确;若为空将返回上一页,如需跳转请传入 url。
- 调试圆点不显示:确认当前环境为非正式版且服务端调试已开启。
- 背景透明度异常:检查 scrollOpacity 是否在 0~1 范围内,并确保父容器未覆盖 opacity。
章节来源
- navbar.wxml:3-27
- navbar.ts:60-77
- env.ts:12-37
结论
该导航栏组件通过全局设备信息计算与灵活的插槽机制,实现了跨设备一致的自定义导航体验。其返回逻辑、透明度控制与调试入口设计兼顾了易用性与安全性。配合页面层的插槽与属性配置,可快速构建符合品牌风格的导航界面。
附录:使用示例与配置
- 在页面 JSON 中引入组件
- 在 app.json 或页面 json 中声明组件路径,以便页面使用。
- 在页面模板中使用
- 通过 <view> 或自定义标签引入 navbar 组件,并设置 title、backgroundColor、titleColor、scrollOpacity、url、showMenu 等属性。
- 使用 left/right/center 插槽自定义左侧、右侧与标题区域内容。
- 事件说明
- 返回按钮:点击后根据 url 跳转或返回上一页。
- 首页按钮:点击后切换到首页 tabBar。
- 调试入口:在非正式版且服务端调试开启时,点击圆点进入调试页。
- 样式定制
- 通过属性覆盖背景与标题颜色。
- 通过插槽完全替换默认布局,实现个性化导航。
- 可在页面层动态更新属性值,实现主题切换。
章节来源
- navbar.ts:12-38
- navbar.wxml:3-27
- navbar.wxss:9-25
- ui.ts:30-47
- env.ts:12-37