项目正在快速迭代中,API 与视觉细节可能随版本调整,请勿用于生产环境。

布局与导航壳 ​

移动页面的骨架由三段组成:顶部导航栏(返回 + 标题 + 右侧动作)、中部内容滚动区(单列信息流)、底部固定区(标签栏或吸底操作栏)。桌面端的「侧边菜单 + 面包屑 + 内容区」三栏结构在移动端整体让位给这一垂直壳,层级关系由页栈导航承担。

完整页面壳 ​

下方演示是一个可交互的最小壳:底部标签栏切换四个真实页签,内容区独立滚动。桌面文档页里它呈现为居中手机列;真机上删除外壳装饰后即为全宽页面(配合 max-width: 420px 的页面壳居中,见适配总览)。

9:41
早上好,李工
9 月 8 日 星期二 · 有 3 个待办
本月报销(元)12,480
待我审批6
进行中项目4
未读消息12
差旅报销单 CL-0908-01
¥1,860 · 待审批
服务器扩容审批
张三提交于 10:24

实现要点:

  • 内容区独立滚动。滚动发生在壳的内容区(overflow-y: auto + overscroll-behavior: contain),标签栏吸底不动,避免整页滚动把标签栏推走。
  • 未读角标实时联动。Tabbar 的角标读数来自页面状态(unreadCount),点按消息或「全部已读」后角标即时消失——标签栏不是静态装饰,必须与页面数据同源。
  • 真机固定吸底 + 安全区自动适配。页面上使用 fixed 默认值:脱离文档流吸底、safe-area-inset-bottom 自动适配全面屏并渲染等高占位;演示壳内用 :fixed="false" 内联(见 Tabbar)。
  • 业务自有吸底元素用 useSafeArea()。悬浮 CTA、吸底提交栏等自绘吸底元素,读取实时 insets 并补写 viewport 标记(不调用它,env() 在缺 viewport-fit=cover 的页面恒为 0):
js
import { useSafeArea, ensureViewportFit } from '@wil-works/evoke-business-ui'

ensureViewportFit()
const safeArea = useSafeArea() // 响应式 { top, bottom, left, right }
html
<div class="float-cta" :style="{ paddingBottom: safeArea.bottom + 'px' }">…</div>

顶部导航栏 ​

二级页面的导航栏承担三件事:返回上一页(替代桌面面包屑,见页面导航)、标注当前位置(标题即位置)、承载页面级动作(右侧动作位放一个高频操作,不放按钮组)。

9:41
订单详情催办
差旅报销单 CL-0908-01审批中
申请人
李工
提交时间
09-08 10:24
报销类型
差旅
关联项目
智慧园区一期
审批轨迹 · 张三已通过
09-08 11:02
审批轨迹 · 财务复核中
待处理

规则:标题始终居中且可截断;右侧动作位只放一个文字级高频操作(如「催办」「保存」),更多操作进底部动作面板(见反馈与浮层),不要在导航栏堆按钮组。

吸底操作栏 ​

表单页的主按钮吸底,与标签栏互斥(一页只保留一个底部固定区)。内容不足一屏时按钮贴近表单,超屏滚动时按钮始终可见。

9:41
新建报销单

吸底栏真机适配:padding-bottom: calc(12px + env(safe-area-inset-bottom)),按钮宽度撑满减去左右 16px 页边距。