# 门户全终端自适应技术实现方案 > 项目:`txw-mhzc-web`(Vue 2.6 + vue-cli 4 + TDesign Vue + Less) > 目标:移动端重新排版 + 平板/桌面/超宽屏统一自适应,兼顾视觉一致性与可用性 > 参考站点:[上海市企业走出去综合服务平台](https://segg.sh.gov.cn/)(固定版心 + 断点响应,非整页 scale) > 版本:v1.0 | 2026-05-26 --- ## 一、方案总览与原则 ### 1.1 技术路线(推荐) 采用 **「CSS 设计令牌 + 断点媒体查询 + 流式布局」** 为主、**「路由级 scale 画布」** 为辅的 **混合方案**: | 场景 | 策略 | 说明 | |------|------|------| | 门户主站(home2、fwsc、gxnlpt、qych 等) | 响应式重排 | 与 [segg.sh.gov.cn](https://segg.sh.gov.cn/) 同类政务门户一致 | | 固定画布子系统(iframe 大屏、部分 mhNewMain) | 可选 `scale` | 仅 `meta.fixedCanvas === true` 的路由启用 | | 禁止 | 全站整页 `transform: scale` | 手机端字糊、触控区缩小、弹层错位 | **视觉一致性** 指:品牌色、版心对齐关系、模块层级、间距节奏在各断点可预测变化,而非「桌面缩小版像素级一致」。 ### 1.2 与现有代码的关系 仓库内已具备基础能力,实施时 **优先激活与统一**,避免重复引入重型框架: | 资产 | 路径 | 状态 | |------|------|------| | 断点常量 | `src/pages/index/styles/breakpoints.less` | 已定义 | | 版心 / 栅格变量 | `src/pages/index/styles/page-layout.less` | 已定义 | | 移动端全局样式 | `src/pages/index/styles/mobile-adaptation.less` | **需在 `main.js` 引入** | | 验证清单 | `docs/test-reports/mobile-adaptation-checklist.md` | 已存在 | | 大屏 scale 试验 | `app.vue` / `mhNewMain.vue` | 与门户主流程隔离 | --- ## 二、开源方案调研与对比(第一部分交付) ### 2.1 筛选标准 - 持续维护(近 12 个月有 release 或活跃 commit) - 社区文档完善、Issue 可检索 - 兼容 iOS 12+、Android 8+、Chrome / Safari / Edge 近两代 - 轻量化:不强制替换 Vue 技术栈 - 集成成本低:与 Vue CLI 4、Less、TDesign 共存 ### 2.2 方案分类说明 自适应实现分四类,**门户类项目通常只需 A + 少量 D**: - **A. CSS 响应式体系**(断点、Grid/Flex、CSS 变量)— 主推 - **B. 构建期单位转换**(px→vw/rem)— 活动页/H5 子模块可选 - **C. 运行时整页 scale**(autofit、v-scale-screen)— 仅大屏/数据可视化 - **D. JS 能力增强**(断点检测、懒加载、resize 节流)— 辅助 以下 **不推荐** 作为门户主方案全量引入:Bootstrap 全量、Element UI 第二套组件库、整站 rem flexible(amfe-flexible)— 与现有 TDesign + Less 变量体系冲突且收益低。 ### 2.3 对比清单 | 方案 | 类型 | 维护 / 生态 | 核心特性 | 适用场景 | 集成流程(概要) | 优点 | 缺点 | |------|------|-------------|----------|----------|------------------|------|------| | **原生 CSS + 项目令牌**(`page-layout` / `breakpoints`) | A | 标准、零依赖 | 变量、@media、Grid、clamp | **门户全站(首选)** | 已有;补 `main.js` 引入 `mobile-adaptation.less` | 可控、无运行时开销、与 Figma 1440 对齐 | 需逐页改样式 | | **TDesign Vue Row/Col + 断点** | A | 腾讯维护 | 24 栅格、`xs/sm/md/lg` | 表单、列表、后台区块 | 已依赖,按文档包一层 | 与组件库一致 | 需熟悉 TDesign 断点 API | | **Tailwind CSS**(项目已部分引入) | A | 活跃 | 工具类、响应式前缀 `md:` | 局部快速排版 | `vue.config` 配 PostCSS;避免与 Less 变量双主源 | 开发快 | 与 Less 混用易混乱,需约束使用范围 | | **postcss-px-to-viewport-modern** | B | 活跃 fork | 设计稿 px 自动转 vw | 375 宽 H5 活动页 | `vue.config.js` → `css.loaderOptions.postcss` | 一稿多宽省事 | 不适合 1200 版心门户;与变量体系冲突 | | **postcss-pxtorem** + lib-flexible | B | 经典但大屏少用 | rem 等比 | 老 H5 | flexible 脚本 + postcss | 移动端成熟 | Vue2 门户性价比低 | | **autofit.js** | C | 活跃 | 整页 scale、ignore 节点 | 1920 固定画布大屏 | `mounted` → `autofit.init({ dw, dh, el })` | 接入极简 | 门户手机不可用 | | **v-scale-screen@1.x** | C | 活跃 | Vue 2.6 组件包裹 scale | 可视化大屏页 | `Vue.use` + 包一层 template | 与 Vue 集成好 | 仅适合大屏路由 | | **@fit-screen/vue** | C | 中等 | Vue2/3 scale 封装 | 同上 | 需 `@vue/composition-api` | 类型友好 | Vue 2.6 多一层依赖 | | **@vueuse/core` `useBreakpoints`** | D | 极活跃 | `matchMedia` 响应式 | 需 JS 切换布局时 | Vue 2.7+ 原生;2.6 用 composition-api | API 优雅 | Vue 2.6 需额外插件 | | **vue-mq / vue-screen** | D | 一般 | 断点 inject | 少量组件切换 | 注册插件 + `$mq` | 简单 | 维护不如 VueUse | | **Container Queries**(原生 CSS) | A | 浏览器已普及 | 按父容器宽度适配卡片 | 卡片、侧栏模块 | `@container` + `container-type` | 比纯 vw 稳 | 需 postcss 插件做旧版兜底(可选) | ### 2.4 本项目推荐组合(集成成本最低) ``` 主路径:page-layout.less + breakpoints.less + mobile-adaptation.less + 各页 @media 组件层:TDesign Grid / Drawer(移动菜单) 增强层:v-lazy(已有清单)+ resize 节流 + ECharts resize 隔离路径:meta.fixedCanvas 路由 → autofit 或 v-scale-screen(可选) ``` **不引入** 新的 UI 框架;**不** 全站 postcss-px-to-viewport;**不** 全站 scale。 --- ## 三、断点设计规范 ### 3.1 断点表(与 Figma / 现有 Less 对齐) | 令牌 | 范围 | 设备 | 版心 / 列数策略 | |------|------|------|-----------------| | `xs` | 0 – 359px | 小屏手机 | 100% 宽,gutter 12px,栅格 1 列 | | `sm` | 360 – 480px | 常规手机 | 100% 宽,gutter 16px,栅格 1 列 | | `md` | 481 – 767px | 大屏手机 / 小平板竖屏 | 100% 宽,gutter 16–36px,栅格 1–2 列 | | `lg` | 768 – 1023px | 平板 | max-width 100%,部分 2 列 | | `xl` | 1024 – 1279px | 小桌面 | 版心可 100% 或保留 padding 40px | | `2xl` | 1280 – 1439px | 标准桌面(Figma 1440 画布) | `--page-content-max-width: 1200px` | | `3xl` | 1440 – 1919px | 宽桌面 | 版心 1200 居中,两侧留白随屏宽增加 | | `4xl` | ≥ 1920px | 超宽屏 | 版心仍 1200;**禁止** 无限制拉伸内容区 | Less 常量(已有,建议扩展): ```less // breakpoints.less @mq-mobile-xs-max: 360px; @mq-mobile-sm-max: 480px; @mq-mobile-max: 767px; @mq-tablet-max: 1023px; @mq-desktop-sm-max: 1279px; @mq-desktop-max: 1439px; @mq-ultrawide-min: 1920px; ``` ### 3.2 媒体查询书写约定 1. **移动优先(推荐新代码)**:默认手机样式 → `min-width` 逐级增强。 2. **桌面优先(兼容旧代码)**:保持现有 `max-width` 块,逐步迁移。 3. **禁止** 同一属性在多个断点反复覆盖且无变量来源。 4. 断点内只改 **CSS 变量** 或 **布局模式**(列数、flex-direction),避免魔法数字散落。 ### 3.3 设计令牌扩展(`:root`) 在 `page-layout.less` 按断点扩展(示例): ```less // 平板 @media (min-width: 768px) and (max-width: 1023px) { :root { --portal-services-fwsc-cols: 2; --page-section-padding-y: 48px; } } // 超宽屏:版心不变,仅增大「出血背景」感知 @media (min-width: 1920px) { :root { --page-content-max-width: 1200px; /* 保持 */ } } ``` --- ## 四、流式布局适配逻辑 ### 4.1 版心模型(与 segg 类门户一致) ``` ┌──────────────────────────────────────────── viewport ────┐ │ margin-auto │ │ ┌──────────────── page-content-max 1200 ─────────────┐ │ │ │ gutter │ content aligned to nav logo │ │ │ └────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────┘ ``` - 容器:`.page-content-wrap` / `.page-nav-inner`(已有) - 宽度:`width: 100%` + `max-width: var(--page-content-max-width)` - 小屏:`--page-content-max-width: 100%`(`mobile-adaptation.less` 已定义) ### 4.2 栅格与模块列数 | 模块 | ≥1280 | 768–1279 | 481–767 | ≤480 | |------|-------|----------|---------|------| | 服务中心四宫格 | 4 列 | 2 列 | 2 列 | 1 列 | | 共性能力卡片 | 3–4 列 | 2 列 | 2 列 | 1 列 | | 页脚链接组 | 横排 | 横排/折行 | 纵排 | 纵排 | | 首页 Hero 搜索 | 横排 | 横排 | 纵排 | 纵排(home2 已部分实现) | 实现方式: ```less .portal-services-grid { display: grid; grid-template-columns: repeat(var(--portal-services-fwsc-cols, 4), minmax(0, 1fr)); gap: var(--portal-services-grid-gap, 24px); } ``` ### 4.3 超宽屏策略 - **内容区不随 4K 变宽**:保持 1200px 版心,避免行长过长。 - **全宽背景** 使用 `.home-section-bleed()`(已有 mixin)铺满视口。 - **装饰性大图** 使用 `max-width: 100%` + 居中,而非拉伸版心。 ### 4.4 大屏固定画布(可选子路由) 仅 `route.meta.layout === 'fixed-canvas'`: ```js scale = Math.min(innerWidth / DESIGN_W, innerHeight / DESIGN_H) ``` 与门户响应式 **路由级隔离**,避免 `app.vue` 全局 scale 影响主站。 --- ## 五、弹性图片与媒体资源 ### 5.1 图片 | 策略 | 实现 | |------|------| | 响应式尺寸 | `max-width: 100%; height: auto;`(mobile-adaptation 已有) | | 分辨率适配 | `` 对 Banner/大图 | | 懒加载 | `loading="lazy"` 或 `v-lazy`(见 checklist) | | 格式 | 优先 WebP(构建或 CDN),PNG 用于透明图标 | | 艺术方向 | 窄屏可选裁切图(`picture` + `source media`) | ### 5.2 视频 / 背景 - 首页 Banner 视频:窄屏降低 `preload`,必要时 `poster` 静帧。 - CSS 背景:`background-size: cover; background-position: center;` - 避免固定 `1920px` 背景宽导致小屏横向滚动(参考政务站仅背景层用 1920 的情况)。 ### 5.3 图标与 SVG - 图标优先 SVG / iconfont,随字号 `em` 缩放。 - Font Awesome 已引入,控制只打包使用子集(长期优化)。 --- ## 六、响应式交互适配策略 ### 6.1 导航 | 断点 | 行为 | |------|------| | ≥768px | 横排菜单(`new-nav` / `nav/index2`) | | <768px | 隐藏横菜单,汉堡 + Drawer/侧滑(`mobile-menu-item` 样式已有) | ### 6.2 触控与表单(WCAG 2.5 目标尺寸) - 可点击区域 **≥ 48×48px**(`mobile-adaptation.less`) - 输入框 `font-size: 16px` 防止 iOS 聚焦放大 - `touch-action: pan-y` 于主滚动容器,减少误触横向滑动 ### 6.3 弹层与固定元素 - TDesign `Dialog` / `Drawer`:窄屏优先 `placement` 全屏或底部抽屉。 - **避免** 在带 `transform` 的 scale 祖先内挂 `position: fixed` 弹层。 - 返回顶部、悬浮客服:小屏抬高 `bottom`,避开安全区: ```css padding-bottom: env(safe-area-inset-bottom, 0); ``` ### 6.4 JS 辅助(按需) ```js // utils/breakpoint.js export const BP = { mobile: 768, tablet: 1024, desktop: 1280 } export function getDeviceClass() { const w = window.innerWidth if (w < BP.mobile) return 'is-mobile' if (w < BP.tablet) return 'is-tablet' if (w < BP.desktop) return 'is-desktop-sm' return 'is-desktop' } ``` 用于:ECharts `resize`、是否加载重动画、Tab 横滑 vs 下拉。 ### 6.5 图表(ECharts) ```js window.addEventListener('resize', throttle(() => chart.resize(), 200)) ``` 移动端 legend 改底部、减小 `grid` 边距,在 `@media` 或 `getDeviceClass()` 分支配置 option。 --- ## 七、性能优化措施 | 项 | 措施 | |----|------| | CSS | 断点样式集中在 `mobile-adaptation.less`,避免每组件重复 `@media` | | 图片 | 懒加载 + 合适尺寸,首屏 LCP 图不用 lazy | | JS | `resize` / `scroll` 监听必须 throttle(200–300ms) | | 字体 | 子集化或系统字体栈回退,减少 FOUT | | 长列表 | 虚拟滚动(TDesign Table 大数据)或分页 | | 动画 | `prefers-reduced-motion: reduce` 关闭非必要动效 | | 构建 | 路由懒加载(已有 vue-router);按页拆分 CSS | --- ## 八、落地实施路线图 ### 阶段 0:基线(1 天) - [ ] `main.js` 增加:`import './styles/mobile-adaptation.less'` - [ ] 确认 `public/index.html` viewport:`width=device-width, initial-scale=1` - [ ] 移除或路由隔离 `app.vue` 未使用的全局 scale 逻辑 - [ ] 统一断点:新代码引用 `breakpoints.less` 变量 ### 阶段 1:全局与导航(2–3 天) - [ ] 导航:移动 Drawer + 桌面横栏双态完整联调 - [ ] `page-layout.less`:补齐 tablet / ultrawide 变量 - [ ] 页脚、面包屑窄屏折行 ### 阶段 2:核心页面重排(5–8 天) 按 checklist 顺序: 1. `home2/index.vue` — 合并零散 `@media` 到变量驱动 2. `fwsc` — 四宫格 + 列表筛选堆叠 3. `gxnlpt` — 侧栏置顶 + 卡片单列 4. `qych` — 法案区块与卡片 每页完成即在 `mobile-adaptation-checklist.md` 打勾。 ### 阶段 3:大屏与回归(2 天) - [ ] ≥1280 / 1920 / 2560 版心居中与背景出血 - [ ] 固定画布子路由(若有)单独测 scale - [ ] 桌面回归:与改版前 1280 对齐 ### 阶段 4:验收 - 真机:iOS Safari、Android Chrome,宽度 320 / 390 / 414 - 桌面:1280、1440、1920、2560 - 工具:Chrome DevTools + Lighthouse 移动端评分 --- ## 九、目录与文件规范(建议) ``` src/pages/index/styles/ breakpoints.less # 断点常量(唯一来源) page-layout.less # 版心、间距令牌 mobile-adaptation.less # 全局移动端 @media mixins/ responsive.less # .respond-to(@bp) 等 mixin(可选新建) src/pages/index/utils/ breakpoint.js # 设备类名 / matchMedia(可选) docs/ responsive-adaptation-implementation-plan.md # 本文档 test-reports/mobile-adaptation-checklist.md # 验收清单 ``` ### Less mixin 示例(可选) ```less .respond-to(@max) when (default()) { @media screen and (max-width: @max) { @content(); } } // 使用 .respond-to(@mq-mobile-max) { .foo { flex-direction: column; } } ``` --- ## 十、风险与决策记录 | 风险 | 缓解 | |------|------| | 双轨样式(桌面 scale + 移动重排)冲突 | 路由 meta 明确 `layout: portal \| fixed-canvas` | | TDesign 组件窄屏溢出 | 表格外包 `.table-scroll-x { overflow-x: auto }` | | 旧页大量魔法 `@media` | 逐页迁移,不一次性重写 | | 超宽屏内容过宽 | 严格 max-width 1200,不改用 scale 撑满 | --- ## 十一、附录:快速集成示例 ### A. 启用全局移动端样式 ```js // main.js import './styles/page-layout.less'; import './styles/mobile-adaptation.less'; ``` ### B. 页面内仅补结构差异 ```vue ``` 列数由 `--portal-services-fwsc-cols` 控制,不在组件内写死 `width: 280px`。 ### C. 可选大屏路由(autofit) ```js // 仅 fixed-canvas 布局的 mounted import autofit from 'autofit.js' autofit.init({ dw: 1920, dh: 1080, el: '#fixed-canvas-root', resize: true }) ``` --- ## 十二、结论 - **移动端重新排版**:依赖 **CSS 变量 + 断点 + Grid/Flex**,激活并扩展现有 `mobile-adaptation.less`,逐页改造核心视图。 - **大屏/超宽屏**:**版心锁定 + 背景出血**,与 [segg.sh.gov.cn](https://segg.sh.gov.cn/) 同类,**不用** 整站 scale。 - **开源框架**:不新增重型 UI 框架;可选 **autofit / v-scale-screen** 仅服务固定画布子系统;主站以 **原生响应式 + TDesign** 为准。 本文档为实施依据,具体排期可与 `mobile-adaptation-checklist.md` 联合跟踪。