218 lines
6.8 KiB
Markdown
218 lines
6.8 KiB
Markdown
# 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
|
||
<el-row :gutter="gutter">
|
||
<el-col :xs="24" :sm="12" :lg="8">...</el-col>
|
||
</el-row>
|
||
```
|
||
|
||
- **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 所列宽度。
|