Files
Neo-ZQYY/_DEL/H5到微信小程序迁移桥接规范_可执行版_v2.md
2026-03-15 10:15:02 +08:00

23 KiB
Raw Blame History

H5 原型 → 微信小程序迁移桥接规范(可执行版 v2.0

适用对象人工开发、AI 批量迁移、代码审查、验收回归
适用范围:本项目上传的 H5 原型页面、配套 CSS/JS、静态资源
目标:在微信原生小程序中实现页面与交互的高还原迁移;除字体渲染细微差异外,样式、层级、动效、状态切换、页面流转尽量 1:1 对齐 H5 验收原型


1. 文档定位

这不是知识笔记,而是执行规程。

使用本规范时AI 或开发者必须做到:

  1. 能从单个 H5 页面产出对应的小程序页面文件。
  2. 能明确哪些能力可直接迁移,哪些必须降级,哪些禁止直迁。
  3. 能在不使用 DOM API 的前提下,把 H5 交互改造成小程序的数据驱动实现。
  4. 能输出可交付物,而不是停留在“分析建议”。

本规范优先级高于旧版桥接文档。若旧版文档与本规范冲突,以本规范为准。


2. 项目级输入与输出契约

2.1 输入物

单页迁移时,输入物必须至少包含:

  • 对应 H5 页面 HTML 文件
  • 该页面引用的 CSS页面内 <style>、独立 css 文件、Tailwind utility
  • 该页面引用的 JS
  • 该页面依赖的图片 / 图标 / SVG / JSON Mock
  • 页面跳转关系和入口参数

2.2 输出物

每个页面迁移后,必须至少产出:

  • pages/<route>/<route>.wxml
  • pages/<route>/<route>.wxss
  • pages/<route>/<route>.js
  • pages/<route>/<route>.json
  • 该页面使用到的 mock 数据文件或页面内 mock 常量
  • 迁移说明(至少包含:状态变量、事件、待确认项、降级项)

2.3 不允许的输出

以下结果视为未完成:

  • 只给“迁移思路”,不产出页面文件
  • 只把 Tailwind class 翻译成 CSS不改 WXML / 交互
  • 继续依赖 document.*window.*history.*localStorage 等浏览器 API
  • 以“兼容性未知”为由保留 H5 写法不处理
  • 把高风险 CSS 特性原样搬过去,且不写降级方案

3. 项目级强制决策

3.1 框架与运行时

  1. 必须使用微信原生小程序页面体系WXML + WXSS + JS + JSON。
  2. 禁止继续在小程序端运行 Tailwind CDN / 浏览器脚本。
  3. 禁止使用 DOM 驱动交互。 页面必须改为数据驱动。
  4. 不引入 Taro / uni-app / WebView 兜底。 本规范面向原生小程序页面迁移。

3.2 验收基准

  1. H5 原型的主要验收基准宽度为 412 CSS px
  2. 小程序以 412 宽设备的视觉效果为主验收目标。
  3. 其他常见宽度设备允许比例差异,但不得出现:文本溢出、遮挡、错层、关键按钮点击区域异常、吸顶/弹层错位。

3.3 单位策略

采用 rpx 为主、px 为辅 的混合单位方案。

  • 优先 rpx:页面宽度、横向布局、卡片尺寸、主容器 padding / margin、列表间距、栅格、吸顶区高度。
  • 优先 px1px 发丝线、阴影 blur/spread、小图标、绝对定位微调、小控件尺寸、状态栏 / 安全区补偿、细描边。
  • 按效果决定:字号、圆角、局部 padding、某些 transform 位移。

换算基准:

rpx = H5_CSS_px × (750 / 412)
    ≈ H5_CSS_px × 1.8204

默认规则:

  • 普通布局值:四舍五入到整数 rpx
  • 视觉敏感值:允许人工微调,不强行套公式
  • 不使用“统一取偶数 rpx”的硬规则

3.4 页面滚动策略

  1. 默认使用 页面自然滚动
  2. 只有在必须做局部滚动区域时,才使用 scroll-view
  3. 吸顶、滚动联动、section 感知优先围绕页面滚动实现;不要无必要把整页包进 scroll-view

3.5 样式组织策略

  1. 全局 token、复用组件样式放 app.wxss 或公共样式文件。
  2. 页面私有样式放页面同名 .wxss
  3. 样式优先使用 class动态值用内联 style 绑定。
  4. 不以 CSS 变量作为唯一运行前提;优先输出静态色值 / 静态 token。若项目后续验证 CSS 变量稳定可用,可作为增强层,不可作为唯一实现路径。

3.6 文本与行高策略 ⚠️

关键发现:微信小程序的 <text> 组件不能直接设置 line-height,必须通过外层 <view> 设置。

全局设置(推荐):

page {
  line-height: 1.5; /* Tailwind 默认行高 */
}

view {
  line-height: inherit; /* view 继承 page 的 line-height */
}

/* text 会自动继承外层 view 的 line-height不需要额外设置 */

局部覆盖:

.section-title {
  font-size: 26rpx;
  line-height: 36rpx; /* 在 view 的 class 上设置text 会继承 */
  font-weight: 600;
}

错误做法:

/* ❌ 直接在 text 上设置 line-height 无效 */
text {
  line-height: 36rpx; /* 不会生效 */
}

执行规则:

  1. 所有文本类样式必须同时设置 font-sizeline-height
  2. line-height 必须在外层 <view> 的 class 上设置,不能在 <text> 上设置
  3. 标准字号的 line-height 换算参考附录 B.3
  4. 若发现 Y 轴高度与 H5 端不一致,优先检查 line-height 是否正确设置

3.7 SVG / 图标策略

  1. 禁止把 H5 的内联 <svg>...</svg> 直接当 WXML DOM 搬运。
  2. 资源层允许 svg 文件进入小程序项目包,但页面显示是否稳定,必须以目标设备实测为准。
  3. 默认执行顺序:
    • 简单静态图标:优先导出为独立资源文件
    • svg 渲染不稳定:转为 png
    • 高频单色图标:允许改为 iconfont / 组件化图标
  4. 动态换色的 SVG 不要临时拼接字符串;应改为多份资源、图标组件或样式控制的等价实现。

4. 技术基线与能力分级

说明:本规范不把“经验上可能可用”的能力写成“完全支持”。 所有能力分三类A 可直接用B 有条件使用C 禁止直迁。

4.1 A 类:可直接使用

以下能力在当前项目中视为稳定迁移能力:

  • app.wxss / 页面 wxss / @import
  • rpx
  • .class#id、元素选择器、::before::after
  • flexposition: relative/absolute/fixed
  • box-shadowborder-radiuslinear-gradient
  • opacity、常规 transform
  • transitionanimation
  • 动态内联样式绑定
  • onPageScroll
  • wx.createAnimation()
  • wx.createSelectorQuery()
  • wx.createIntersectionObserver()
  • navigator / wx.navigateTo / wx.redirectTo / wx.switchTab / wx.navigateBack
  • view / navigatorhover-class

4.2 B 类:有条件使用,必须带回退或验证

以下能力允许使用,但不能把它们当成项目硬依赖:

  • position: sticky
  • grid
  • filter: blur()
  • backdrop-filter
  • clip-path
  • vh
  • line-clamp
  • 复杂组合选择器
  • 资源型 svg
  • CSS 变量

执行规则:

  1. 使用前必须确认该页面已有回退方案。
  2. 若页面对视觉或交互依赖度高,则必须做真机验证。
  3. 若 B 类能力失效,不得阻塞交付,必须切换为本规范定义的降级实现。

4.3 C 类:禁止直迁

以下能力不得原样从 H5 搬到小程序:

  • document.getElementById/querySelector/querySelectorAll
  • classList.add/remove/toggle
  • 直接改 element.style.xxx
  • innerHTML / textContent 方式渲染视图
  • window.scrollY / window.scrollTo
  • history.back
  • localStorage / sessionStorage
  • alert / confirm
  • CSS env(safe-area-inset-*)
  • :hover / group-hover:*
  • 依赖浏览器焦点模型的 :focus / :active 交互
  • 依赖 :first-child/:last-child/:nth-child 才能成立的视觉规则

5. 页面转换的标准执行流程

每迁移 1 个页面,都必须按以下顺序执行。

步骤 1页面资产盘点

输入HTML / CSS / JS / 图片资源

动作:

  • 抽取页面标题、路由名、入口参数、返回路径
  • 列出页面块顶部、卡片区、列表区、底部操作区、弹层、浮层、Toast
  • 列出页面状态:默认态、空态、加载态、错误态、选中态、展开态、禁用态
  • 列出页面动效:淡入、位移、缩放、吸顶、滚动联动、长按、评分拖动

输出:页面迁移卡

步骤 2结构改写为 WXML 语义树

动作:

  • divview
  • 文本优先用 text
  • 图片用 image
  • 链接/跳转用 navigatorbindtap
  • 表单元素替换为原生小程序组件
  • 列表一律改为 wx:for
  • 条件显示一律改为 wx:if / hidden / 条件 class

禁止:

  • 保留 H5 DOM 层级只是把标签名替换一下
  • text 内嵌套 view
  • 用字符串拼接 HTML 片段

步骤 3Tailwind 与自定义 CSS 拆解

动作:

  • 先按视觉功能拆成:布局、尺寸、文本、颜色、装饰、状态、动画
  • 再判断每个值使用 rpx 还是 px
  • 统一抽出公共 token不允许每页各自发散命名

要求:

  • 不保留“一长串 utility class 直接照搬”的中间态
  • 对频繁出现的组合样式抽成语义类,如 .card.section-title.tab--active

步骤 4交互从 DOM 驱动改为数据驱动

动作:

  • 把所有 DOM 查询改成状态变量
  • 把显隐、激活、展开、选中、校验、加载都改成 data 驱动
  • 把滚动联动改成 onPageScroll + 节流 + 仅在状态变化时 setData

输出:状态表

状态表至少包含:

  • 状态变量名
  • 默认值
  • 可选值
  • 受哪个事件修改
  • 影响哪些视图

步骤 5页面级动效实现

执行规则:

  • 纯显隐 / 透明度 / 位移 / 简单位移动画:优先 transition / animation
  • 需要顺序编排、组合变换、受事件精确驱动:用 wx.createAnimation()
  • 高频交互不要每帧 setData

步骤 6导航与参数改造

动作:

  • 普通页面:wx.navigateTo
  • 替换当前页:wx.redirectTo
  • tabBar 页面:wx.switchTab
  • 返回:wx.navigateBack
  • 页面参数:统一在 onLoad(query) 中读取

步骤 7安全区与导航栏补偿

动作:

  • 禁止使用 env(safe-area-inset-*)
  • 通过系统信息计算状态栏与底部安全区
  • 自定义导航栏页面必须统一实现,不得一页一套

步骤 8Mock 数据接入

动作:

  • 页面先用 mock 跑通
  • 模板静态文案与后端数据字段分开
  • 所有列表、徽标、状态标签都要有 mock

步骤 9真机回归与像素微调

动作:

  • 先看 412 宽主验收设备
  • 再看至少一台 375 宽设备
  • 出现不对齐时优先微调局部 px/rpx,不要推翻整体单位策略

步骤 10记录迁移说明

每页必须输出迁移说明,至少包含:

  • 页面依赖资源
  • 迁移状态变量
  • 高风险点
  • 已做降级项
  • 待后端对接字段
  • 待真机复核项

6. Tailwind → WXSS 的执行规则

6.1 间距与尺寸

执行原则:

  1. 标准 spacing 先换算为 H5 实际 px再决定 rpx / px
  2. 主容器、卡片、列表间距优先 rpx
  3. 图标、徽标、定位补偿优先 px
  4. arbitrary 值不能偷懒统一换 rpx,必须逐项判断。

建议 token412 基准)

H5 px 建议值
4px 8rpx
8px 14rpx
12px 22rpx
16px 29~30rpx
20px 36rpx
24px 44rpx
32px 58rpx
40px 72rpx

说明:

  • 16px 允许落在 29rpx 或 30rpx以真机比对为准。
  • 阴影参数不要强制 rpx 化;优先保留 px 质感。

6.2 文本

标准字号类

对 Tailwind 标准字号类,迁移时应同时输出 font-sizeline-height

arbitrary 字号

规则:

  1. text-[Npx] 不能直接假设其 line-height = 1.2 倍字号。
  2. 若原型页面显式设置了 leading-*,以显式值为准。
  3. 若未显式设置,则应从原型的实际计算样式、截图观感或上下文排版需求确定行高。
  4. 对单行标签/徽章文字,可使用更紧的 line-height对正文、说明文必须按真实视觉高度定。

禁止:

  • 在全项目层面硬编码“所有 arbitrary 字号默认 1.2 倍行高”

6.3 颜色

执行原则:

  1. 颜色优先输出静态十六进制 / rgba()
  2. Tailwind 透明度修饰符转成 rgba()
  3. 若项目后续统一做 token 化,可再抽公共常量;首轮迁移不要把颜色系统设计复杂化。

6.4 布局

Flex

默认首选。能用 flex 做出来的布局,不优先上 grid。

Grid

仅在以下条件同时满足时允许:

  • 页面是规则网格
  • 列数固定
  • 没有复杂跨列
  • 真机验证通过

否则改用 flex + wrap + 固定宽度 / 百分比。

6.5 组合类

以下 Tailwind 组合迁移时不要机械翻译:

  • space-y-*
  • divide-y
  • group-hover:*
  • peer-*
  • hover:*
  • focus:*
  • active:*

迁移规则:

  • space-y-*:优先给循环项单独 class选择器方案仅作受控场景补充
  • divide-y:优先对列表项显式加边线 class并根据 index 控首项
  • hover:*:改 hover-class 或按压反馈
  • focus:*:用 bindfocus/bindblur + 状态 class

7. HTML / 事件 / API 的标准映射

7.1 标签映射

H5 小程序
div view
span text
p view / text
img image
a navigator / view bindtap
button button / view bindtap
input input
textarea textarea
ul/ol/li view + wx:for
select picker

补充规则:

  • imagemode 必须按原图展示意图设置,不允许默认留空就交付。
  • object-fit: cover 常映射为 aspectFill;但若原图不能被裁切,则应改为 aspectFit

7.2 事件映射

H5 小程序
onclick bindtap
oninput bindinput
onchange bindchange
onscroll bindscroll / onPageScroll
ontouchstart bindtouchstart
ontouchmove bindtouchmove
ontouchend bindtouchend
oncontextmenu bindlongpress

注意:这只是常见替换,不代表浏览器事件语义与小程序事件语义完全等价。

7.3 冒泡与阻断

  • bind*:正常冒泡
  • catch*:阻止事件向上冒泡

弹层、蒙层、内部内容区必须明确设计谁冒泡、谁拦截,不能边做边猜。

7.4 常见浏览器 API 替代

H5 小程序
history.back() wx.navigateBack()
window.location.href wx.navigateTo()
window.location.replace wx.redirectTo()
tab 页跳转 wx.switchTab()
window.scrollY onPageScroll().scrollTop
navigator.clipboard.writeText wx.setClipboardData()
localStorage wx.setStorageSync/getStorageSync
alert/confirm wx.showToast/wx.showModal

8. JS 交互模式的标准改写

8.1 显隐切换

H5 的 classList.add/remove('hidden') 一律改为:

  • wx:if
  • hidden
  • 或状态 class

默认建议:

  • 大块弹层:wx:if
  • 仅做过渡且结构稳定:状态 class + transition

8.2 Tab / 选中态

统一改为单一状态变量:

Page({
  data: { activeTab: 'basic' },
  onTabChange(e) {
    this.setData({ activeTab: e.currentTarget.dataset.tab })
  }
})

禁止:

  • 同时维护多个布尔值表示同一个 tab 组选中态

8.3 展开 / 收起

统一改为对象映射或数组项状态,不允许操作 DOM 文本改按钮文案。

8.4 滚动联动

执行规则:

  1. onPageScroll 只在确实需要时声明。
  2. 必须节流或去抖。
  3. 只在状态变化时 setData
  4. 吸顶标题、目录高亮、section 感知,优先用 IntersectionObserver

8.5 长按菜单

原型中的“卡片旁锚点弹出菜单”在小程序中优先改为:

  • 底部 action sheet
  • 或固定底部操作面板

原因:

  • 更稳定
  • 更易复用
  • 更符合触屏交互

8.6 评分拖动 / 拖拽类交互

规则:

  1. 触摸起始时缓存容器 rect。
  2. touchmove 中仅基于缓存坐标计算,不每次重新 query。
  3. 评分变化只在值变化时更新。

8.7 Toast / 短提示

优先级:

  1. 系统 wx.showToast
  2. 若原型要求强定制视觉,再做自定义 toast 组件

8.8 动画

优先级:

  1. WXSS transition / animation
  2. wx.createAnimation()
  3. 避免高频 setData 驱动逐帧动画

9. 高风险能力的强制降级规则

9.1 sticky

执行顺序:

  1. 页面自然滚动场景:先尝试 position: sticky
  2. 若在 scroll-view 中:不要硬上 sticky改为滚动监听/观察者驱动
  3. 多层 sticky只保留最外层 sticky

9.2 backdrop-filter

规则:

  • 不作为交付必需能力
  • 默认必须提供半透明背景降级
  • 若失效,不得阻塞上线

9.3 vh

规则:

  • 不把 100vh 当成万能全屏高度
  • 涉及自定义导航栏、安全区、底部操作栏的页面,必须计算可用高度
  • 能用 min-height + 内边距解决的,不强依赖 vh

9.4 复杂选择器

规则:

  • WXSS 公开支持的基础选择器以 .class#id、元素、::before/::after 为准
  • 组合选择器只在局部受控场景下使用
  • 不把复杂结构选择器写成项目标准手段

9.5 CSS 变量

规则:

  • 首轮迁移不强制依赖 var()
  • 颜色、渐变、阴影优先输出静态值
  • 若后续项目验证 CSS 变量稳定可用,可作为增强重构项,不是首轮交付阻塞项

10. 模板内容与数据内容的边界

每个页面都要把内容拆成三类:

10.1 模板固化内容

这些通常写死在页面模板或常量里:

  • 页面标题
  • 分区标题
  • 固定按钮文案
  • 空态文案
  • Tooltip 固定说明
  • 表头 / 标签名

10.2 Mock / 后端数据内容

这些必须抽成数据:

  • 卡片列表
  • 客户信息
  • 任务信息
  • 看板统计值
  • 徽标状态
  • 提示数量
  • 聊天记录
  • 备注内容
  • 评分值
  • 时间轴 / 历史记录

10.3 前端派生内容

这些应由前端根据后端字段计算:

  • 状态色 class
  • 选中态 class
  • 进度条宽度
  • 文案格式化
  • 百分比显示
  • 数字千分位
  • 是否显示空态 / 加载态 / 错误态

11. 页面目录与公共层建议结构

app.js
app.json
app.wxss

/common
  /styles
    tokens.wxss
    mixins.wxss
    animation.wxss
  /utils
    format.js
    system.js
    nav.js
  /mock
    xxx.js
  /components
    app-navbar/
    app-tab/
    app-card/
    app-empty/
    app-toast/
    app-action-sheet/

/pages
  /task-list
  /task-detail
  /board-finance
  /board-customer
  /board-coach
  /notes
  /chat
  ...

/assets
  /images
  /icons

执行要求:

  • 可复用的组件必须抽离
  • 不允许把每页都做成孤岛
  • 但也禁止首轮过度抽象,影响交付速度

12. 每页迁移完成的验收清单

以下清单必须全部勾过,页面才算完成。

12.1 结构

  • 页面可正常进入
  • 路由与参数正确
  • 结构层级与原型一致
  • 图片、图标、背景都已替换到位

12.2 样式

  • 主布局宽度、边距、卡片尺寸与原型接近
  • 文本字号、行高、字重合理
  • 圆角、边框、阴影、渐变已还原
  • 吸顶、弹层、底栏无错位
  • 412 宽设备通过视觉验收

12.3 交互

  • 点击反馈存在
  • tab 切换正确
  • 弹层开关正确
  • 长按 / 复制 / 展开 / 收起 / 评分等交互正确
  • 返回和跳转链路正确

12.4 性能

  • 滚动时无明显抖动
  • 没有在高频事件中无脑 setData
  • 动画不依赖逐帧 JS

12.5 风险项

  • 所有降级项已记录
  • 所有待真机复核项已记录
  • 所有待接口对接字段已记录

13. AI 执行模板(标准提示词契约)

以下模板用于驱动 AI 按页迁移。

你现在负责把指定 H5 页面迁移为微信原生小程序页面。

必须遵守以下约束:
1. 输出原生小程序文件wxml / wxss / js / json。
2. 禁止使用任何 DOM API、window、history、localStorage。
3. 禁止继续依赖 Tailwind 运行时;需将 Tailwind 与页面自定义样式改写为可维护的 WXSS。
4. 视觉目标是最大程度还原 H5默认以 412 宽设备为验收基准。
5. 单位策略为 rpx 为主、px 为辅:布局主尺寸优先 rpx发丝线/小图标/阴影/绝对定位微调优先 px。
6. 所有交互必须改为数据驱动。
7. 对 sticky / backdrop-filter / svg / vh / grid 等高风险能力,必须给出降级或验证说明。
8. 每输出一个页面,必须附带:
   - 页面状态变量表
   - 事件处理函数表
   - mock 数据结构
   - 未决问题与降级项

请按以下顺序输出:
A. 页面迁移摘要
B. 目录结构
C. WXML
D. WXSS
E. JS
F. JSON
G. mock 数据
H. 迁移说明与风险项

13.1 AI 页面状态表模板

| 状态变量 | 类型 | 默认值 | 可选值 | 影响视图 | 触发事件 |
|---|---|---:|---|---|---|
| showFilter | boolean | false | true/false | 筛选面板 | onToggleFilter |
| activeTab | string | overview | overview/detail/... | tab内容区 | onTabChange |

13.2 AI 风险项模板

- 已降级backdrop-filter 改为半透明背景
- 待验证:顶部 sticky 在真机 Android 上需复核
- 待后端:客户列表、统计卡片、备注列表当前仍为 mock

14. 本项目对旧版桥接文档的修订结论

旧版文档可继续参考,但以下内容不再作为硬规范:

  1. 不再把大量现代 CSS 特性写成“完全支持”。
  2. 不再把 arbitrary 字号 line-height 的经验值当成定理。
  3. 不再把 CSS 变量当成首轮必选依赖。
  4. 不再把 .parent > view + view 这类技巧写成唯一实现方案。
  5. 不再把 <image src="xxx.svg"> 写成无条件可靠方案。
  6. 不再允许“先翻样式,交互以后再说”的半迁移状态作为交付完成。

15. 参考文档(执行时必须优先查官方)

微信小程序官方 / 腾讯云镜像:

Tailwind 官方:


16. 最终执行口径

本项目的小程序迁移,不是“把 Tailwind 翻译成 WXSS”这么简单。

真正的执行标准是:

  1. 页面结构重写为 WXML
  2. 样式收敛为可维护的 WXSS
  3. 交互全部改为小程序数据驱动;
  4. 对高风险 CSS 特性提供可交付降级;
  5. 每页都有 mock、状态表、事件表、风险说明和验收清单。

能做到这 5 条,才算“可执行版桥接规范”。