# PC / 移动端响应式规范 > 适用项目:`schedule-invest-plan` > 版本:v1.0 > 策略:**Mobile First(移动优先)** + 单代码库适配 PC 与移动端浏览器 --- ## 1. 目标与原则 | 原则 | 说明 | |------|------| | 一套代码 | 不维护独立 H5 仓库,通过断点与布局组件适配 | | 移动优先 | 默认样式面向小屏;使用 `min-width` 媒体查询逐级增强 | | 流式布局 | 宽度优先 `%` / `fr` / `max-width`,避免写死大屏像素宽度 | | 触控友好 | 可点击区域最小 **44×44px**(含按钮、图标按钮) | | 与 Element Plus 一致 | 栅格、表单 `label-position`、对话框宽度遵循 EP 响应式用法 | | 主题无关 | 深浅色只改 CSS 变量,不改变断点与间距阶梯 | --- ## 2. 视口与设备范围 - **最小支持宽度**:320px(`body` 已设置 `min-width: 320px`) - **主要适配对象**: - 移动端:竖屏手机(320–767px) - 平板:768–1023px - PC:≥1024px - **HTML**:保留 `viewport` meta,禁止用户缩放锁死(不设 `user-scalable=no`),以保证无障碍与系统字体缩放。 --- ## 3. 断点定义(统一来源) 断点数值以 **`src/constants/breakpoints.ts`** 为 JS/TS 唯一真相;SCSS 使用 **`src/styles/breakpoints.scss`**(数值须与 TS 保持一致)。 | 令牌 | 宽度 | 典型场景 | |------|------|----------| | `sm` | ≥576px | 大屏手机横屏、小平板 | | `md` | ≥768px | 平板竖屏 | | `lg` | ≥1024px | 笔记本 / PC 主内容区 | | `xl` | ≥1280px | 宽屏,内容区达到 `max-width` | ### 3.1 语义化设备类型(业务判断用) 在脚本中通过 **`useBreakpoint()`** 获取(勿在各页面重复 `resize` 监听): | 字段 | 条件 | 用途示例 | |------|------|----------| | `isMobile` | 宽度 < 768px | 表单单列、`label-position="top"` | | `isTablet` | 768px ≤ 宽度 < 1024px | 双列栅格 | | `isDesktop` | 宽度 ≥ 1024px | 侧栏 + 主内容 | | `isWide` | 宽度 ≥ 1280px | 宽表、多列看板 | --- ## 4. 布局规范 ### 4.1 页面壳层 ``` #app └── .app-shell (min-height: 100vh) └── .app-container (max-width + 水平居中 + 内边距) ├── AppHeader └── AppPage / 页面内容 ``` - **内容最大宽度**:`1280px`(`--layout-max-width`) - **页面内边距**:使用 CSS 变量,禁止在业务页写死 `padding: 32px`: | 变量 | 移动端(<768) | 平板(≥768) | PC(≥1024) | |------|------------------|--------------|--------------| | `--page-padding-x` | 16px | 24px | 32px | | `--page-padding-y` | 16px | 24px | 32px | ### 4.2 页面组件 - 路由级视图根节点使用 **`AppPage`**(`src/components/layout/AppPage.vue`),类名 `app-page`。 - 需要全宽区块(如顶栏下横幅)时,在 `AppPage` 内再包一层 `.app-page__section`,通过负 margin 拉满(见组件注释,慎用)。 ### 4.3 Element Plus 栅格 ```vue ... ``` - **gutter**:移动端 `12`,PC `20`(可用 `useBreakpoint().isMobile` 计算)。 - 默认单列:`xs="24"`,再按 `sm` / `md` / `lg` 递增列数。 ### 4.4 表单 | 场景 | 规范 | |------|------| | 移动端 | `label-position="top"`,`size="default"` 或 `large` | | PC | `label-position="right"`,`label-width` 统一(如 `100px`) | | 按钮区 | 移动端主按钮 `width: 100%` 或 `el-button` 块级排列 | ### 4.5 表格 - 移动端:优先 **卡片列表** 或 **横向滚动**(`el-table` 外包 `.app-table-scroll`),避免压缩到不可读。 - PC:常规表格;列过多时使用 `fixed` 与 `min-width`。 --- ## 5. 样式编写规范(Sass) ### 5.1 媒体查询 统一使用 **`src/styles/mixins/_respond.scss`** 中的 mixin(已在 Vite 中全局注入): ```scss .app-card { padding: 12px; @include respond-up(md) { padding: 16px; } @include respond-up(lg) { padding: 20px; } } .app-toolbar { @include respond-down(md) { flex-direction: column; align-items: stretch; } } ``` | Mixin | 含义 | |-------|------| | `respond-up($name)` | `min-width`,从该断点起生效 | | `respond-down($name)` | `max-width`,小于该断点生效 | | `respond-between($from, $to)` | 闭开区间,用于仅平板样式 | **禁止**在业务组件中手写零散 `@media (max-width: 750px)`,除非规范文档修订并同步 `breakpoints.scss`。 ### 5.2 尺寸与字体 - 间距使用 **4px 基准**:4、8、12、16、24、32、48。 - 正文字号:移动 **14px**,PC **14–16px**(`--font-size-base`)。 - 标题:移动比 PC 小一级(如 `h1` 移动 20px,PC 24px)。 ### 5.3 颜色与主题 - 业务样式只引用 **`var(--color-*)`**,不写死 `#fff` / `#000`(图表等特殊场景除外)。 --- ## 6. 脚本与组合式 API ```ts import { useBreakpoint } from '@/composables/useBreakpoint' const { isMobile, isDesktop, width } = useBreakpoint() ``` - 仅当 **布局结构** 或 **组件属性** 需要切换时使用(如 `label-position`)。 - 不要用 `width` 做业务权限或接口参数。 --- ## 7. 导航与顶栏 - **PC**:标题与导航同一行,控件横向排列。 - **移动**:标题独占一行;导航与语言/主题控件换行,选择器 **等分或 100% 宽**。 - 路由跳转须保留 URL 上的 `lang`、`theme`(`useRouteWithPreferences`)。 --- ## 8. 测试与验收 | 类型 | 要求 | |------|------| | 浏览器 | Chrome 最新 + Safari iOS / Android Chrome 各一 | | 断点抽测 | 375、414、768、1024、1280 宽度无横向滚动条(除表格滚动容器) | | 横竖屏 | 图表与弹层在旋转后 `resize` 正常 | | 无障碍 | 焦点可见;表单控件具备 `aria-label` 或可见 label | --- ## 9. 禁止事项 - 禁止为 PC / H5 复制两套页面文件(除非产品明确要求独立路由)。 - 禁止 `position: fixed` 大面积遮挡而不留安全区(刘海屏注意 `env(safe-area-inset-*)` 后续扩展)。 - 禁止在 <768px 使用 hover 作为唯一交互提示。 - 禁止未读规范即新增断点数值。 --- ## 10. 相关文件索引 | 文件 | 职责 | |------|------| | `src/constants/breakpoints.ts` | 断点像素、设备语义 | | `src/composables/useBreakpoint.ts` | 响应式设备状态 | | `src/styles/breakpoints.scss` | Sass 断点 Map | | `src/styles/mixins/_respond.scss` | 媒体查询 mixin | | `src/styles/layout.scss` | 壳层与工具类 | | `src/components/layout/AppPage.vue` | 页面根布局 | | `docs/RESPONSIVE_SPEC.md` | 本文档 | --- ## 11. 变更流程 修改断点或间距阶梯时须: 1. 同步更新 `breakpoints.ts` 与 `breakpoints.scss`; 2. 更新本文档版本号与变更说明; 3. 在 `IMPACT_ANALYSIS.md` 中注明是否影响既有页面布局; 4. 回归测试 §9 所列宽度。