V5: 移动端 —— 「手机上也能用吗?」
出差的同事在微信群里吐槽:“手机上打开报销页面,按钮小得根本点不到,表格都挤在一起,每次都要放大缩小才能用。“老板顺手截图转发给你,加了一句”搞一下”。
你打开手机一看——确实,桌面端的三栏布局硬塞进 375px 宽的屏幕里,输入框要精确点击,下拉菜单被键盘挡住,日期选择器弹窗超出屏幕。这不是”改个样式”的事,是整个交互模式需要重新思考。
当前状态 (V4):系统已有完整的增删改查、JWT 鉴权、Redis 缓存、分页、乐观锁、事务、幂等。但前端只考虑了桌面浏览器。
问题分析(5 层框架)
Section titled “问题分析(5 层框架)”| 层级 | 问题 | 影响 |
|---|---|---|
| 表象 | 手机上按钮太小、表格溢出 | 用户无法正常操作 |
| 直接原因 | CSS 使用固定宽度,未做响应式 | 小屏幕布局崩溃 |
| 系统原因 | 前端架构没有 mobile-first 设计 | 所有组件都需要调整 |
| 设计缺失 | 缺少移动端专属交互模式 | 触摸操作不友好 |
| 根本原因 | 没有考虑多端访问场景 | 出差/外勤场景完全不可用 |
- 触摸目标最小 44x44px(Apple HIG)/ 48x48dp(Material Design)
- 移动端用户的核心操作:快速记一笔 > 查看列表 > 审批
- 弱网环境(地铁/电梯)需要离线容错
graph TD Phone["📱 手机"] --> API PC["💻 电脑"] --> API Tablet["📱 平板"] --> API API["统一 REST API<br/>Go/Gin 后端"] --> Redis["Redis"] API --> DB["PostgreSQL"]关键变化:API 标准化 + 响应式前端 解决:手机/平板/电脑都能正常使用
| 决策点 | 选项 A | 选项 B | 选择 | 理由 |
|---|---|---|---|---|
| 技术路线 | 开发独立 App | 响应式 Web + PWA | B | 团队没有移动端开发经验,PWA 覆盖 90% 需求 |
| CSS 策略 | 桌面优先加 media query | Mobile-first + Tailwind 断点 | B | Tailwind 默认就是 mobile-first |
| 移动端导航 | 顶部菜单折叠 | 底部 Tab 栏 | B | 拇指热区友好,符合移动端习惯 |
| 表格展示 | 横向滚动表格 | 卡片式列表 | B | 卡片在小屏上信息密度更合理 |
| 快速记账 | 跳转完整表单 | 底部弹出简化表单 | B | 减少页面跳转,降低操作摩擦 |
前端改造(不涉及后端 API 变更):├── Tailwind 响应式断点:sm(640) / md(768) / lg(1024)├── 移动端布局:底部 Tab + 卡片列表 + 快速记账浮窗├── PWA:manifest.json + service-worker(缓存静态资源)└── 触摸优化:大按钮、滑动手势、防误触- 全局布局响应式:
lg:以上走桌面三栏,md:以下切换为单栏 + 底部导航 - 列表页:桌面用表格,移动端用卡片(
hidden lg:table/lg:hidden) - 快速记账:移动端首页常驻”+“按钮,弹出简化表单(金额 + 分类 + 备注)
- PWA manifest:支持”添加到主屏幕”,配置
display: standalone - HTTP 缓存头:静态资源设置
Cache-Control,API 响应设置合理的缓存策略
给 AI 的 Prompt
Section titled “给 AI 的 Prompt”我有一个 Go(Gin) + React + Tailwind CSS 的团队记账工具(报销管理系统)。当前前端只适配了桌面端,需要做移动端适配。
技术栈:React 19 + Vite + Tailwind CSS v4 + React Router v7
请帮我完成以下改造:
1. **全局响应式布局** - 桌面端(lg 以上):保持现有侧边栏 + 内容区布局 - 移动端(lg 以下):隐藏侧边栏,底部添加 Tab 导航栏(首页/列表/我的) - Tab 栏高度 56px,图标 + 文字,当前页高亮 - 底部导航组件:BottomNav.jsx
2. **报销列表移动端卡片视图** - 桌面端保持表格(加 class `hidden lg:block`) - 移动端用卡片列表(加 class `lg:hidden`) - 每张卡片显示:金额(大字)、分类标签、日期、状态徽章 - 卡片最小高度 72px,整个卡片可点击进详情 - 支持下拉刷新提示
3. **快速记账浮窗** - 移动端右下角 FAB 按钮(56x56px,圆形,阴影) - 点击弹出 bottom sheet(从底部滑出的半屏表单) - 表单字段:金额(数字键盘)、分类(横向滚动标签选择)、备注(可选) - 提交后自动关闭,显示 toast 成功提示
4. **触摸优化** - 所有可点击元素最小 44x44px(用 Tailwind: `min-h-[44px] min-w-[44px]`) - 按钮之间间距至少 8px - 输入框高度 48px,字号 16px(防止 iOS 自动缩放) - 表单 label 和 input 纵向排列(移动端不要横向并排)
5. **PWA 配置** - 创建 public/manifest.json:name="团队记账",short_name="记账", display="standalone",theme_color="#3B82F6" - index.html 添加 manifest link 和 meta viewport - 简单的 service worker:缓存 App Shell(HTML/CSS/JS)
6. **后端 HTTP 缓存头**(Go/Gin) - 静态资源:`Cache-Control: public, max-age=31536000, immutable`(Vite 带 hash) - API 响应:`Cache-Control: private, no-cache`(走 Redis 缓存即可) - 添加 ETag 中间件用于静态资源
请给出完整的代码文件,保持与现有项目结构一致。- Chrome DevTools 切换到 iPhone SE(375px):布局不溢出,无横向滚动
- 切换到 iPad(768px):合理利用空间,不过于拥挤
- 桌面端(1024px+):保持原有布局不变
- 底部 Tab 导航正常切换页面,当前页高亮
- 快速记账浮窗弹出/收起动画流畅
- 快速记账提交后列表自动刷新
- 所有按钮手指可以轻松点击(不需要精确瞄准)
- 输入框获得焦点时键盘不挡住当前输入
- 下拉选择器在移动端可正常使用
- iOS Safari 输入框不会触发页面自动缩放(字号 >= 16px)
PWA 验证
Section titled “PWA 验证”-
lighthousePWA 检测通过基本项 - 浏览器显示”添加到主屏幕”提示
- 从主屏幕打开无浏览器地址栏(standalone 模式)
- 断网后 App Shell 可加载(静态资源已缓存)
- 带 hash 的静态资源响应头包含
Cache-Control: public, max-age=31536000 - API 响应头包含
Cache-Control: private, no-cache - 二次加载页面,静态资源走 disk cache(DevTools Network 查看)
你学到了什么
Section titled “你学到了什么”| 主题 | 对应模块 |
|---|---|
| 响应式设计不是”加 media query”,是重新思考交互模式 | → Module 1 (API设计) |
| Mobile-first 意味着默认样式服务于最小屏幕 | → Module 1 |
| HTTP 缓存分层:浏览器缓存 → CDN → 应用缓存 → Redis | → Module 13 (HTTP缓存) |
| Cache-Control 的 public/private/no-cache/immutable 区别 | → Module 13 |
| PWA 是渐进增强,不是推翻重来 | → Module 1 |
| Service Worker 生命周期:install → activate → fetch | → Module 13 |
1. iOS Safari 输入框自动缩放
Section titled “1. iOS Safari 输入框自动缩放”现象:点击输入框页面突然放大,用户迷惑。
原因:iOS Safari 对 font-size < 16px 的 input 会自动缩放。
解决:输入框字号设为 16px,或在 viewport meta 加 maximum-scale=1(不推荐,影响可访问性)。
2. 100vh 在移动端不等于可见高度
Section titled “2. 100vh 在移动端不等于可见高度”现象:底部导航被浏览器工具栏挡住。
原因:移动浏览器的地址栏/工具栏占用空间但不算在 100vh 里。
解决:用 100dvh(dynamic viewport height)或 JS 计算 window.innerHeight。
3. 快速记账表单重复提交
Section titled “3. 快速记账表单重复提交”现象:网络慢时用户连点提交,创建了多条重复记录。 原因:移动端网络延迟更高,用户以为没反应。 解决:提交后立即 disable 按钮 + 显示 loading 态 + 后端幂等(V4 已有)。
4. 响应式断点选错
Section titled “4. 响应式断点选错”现象:在某些设备上布局”半桌面半移动”很难看。 原因:断点设置不合理,或者在断点附近没有测试。 解决:用 Tailwind 默认断点(sm/md/lg/xl),重点测试 768px 附近的过渡。
5. PWA 缓存更新不生效
Section titled “5. PWA 缓存更新不生效”现象:发布新版后用户看到的还是旧版。
原因:Service Worker 缓存了旧的 App Shell,没有更新策略。
解决:使用 stale-while-revalidate 策略,或在 SW 更新时提示用户刷新。