坑的本质:三端对同一能力的实现并不一致
多端框架解决的是「语法统一」,不是「行为统一」。同一个业务动作,三端底层可能是完全不同的接口:微信有 wx.login,抖音有 tt.login,App 侧则要走手机号或第三方 OAuth。组件同样如此,button 上挂的 open-type 取值集合在各端并不相同。
因此适配的重点不是「少写代码」,而是让差异有唯一出口。
高频差异清单
| 差异类型 | 典型表现 |
|---|---|
| 组件属性 | button 的 open-type 取值不同;canvas、video 的属性与事件名存在差异 |
| 平台 API | 登录、支付、分享、订阅消息、剪贴板等接口名与返回结构不同 |
| 生命周期 | 冷启动/热启动时 onLaunch 与 onShow 的时序在各端略有差异 |
| 样式与布局 | 安全区适配、自定义导航栏高度、状态栏高度的获取方式不一致 |
把这些差异列成清单并落成文档,比记在个人经验里可靠得多——因为清单可以交给下一位接手的同学。
隔离方案:条件编译 + 运行时探测
差异处理分两类:
1. 编译期就能确定的差异(「这段逻辑只在微信端存在」):用条件编译处理。
// #ifdef MP-WEIXIN
return weixinShare(options)
// #endif
// #ifdef MP-TOUTIAO
return toutiaoShare(options)
// #endif
2. 编译期无法确定的差异(同一端内还存在设备或版本差异):用运行时能力探测,例如通过 uni.canIUse() 判断 API 是否可用、读取 uni.getSystemInfoSync().uniPlatform 判断运行平台,在不支持时降级而不是报错。
两条原则:不在页面里直接出现 wx.、tt. 前缀;所有端差异统一收敛到 utils/platform 网关,页面只调用网关暴露的统一函数。
三条关键链路怎么处理
- 登录:各端先拿到临时凭证(微信
code、抖音相应票据),统一由后端换取会话标识,前端只负责「拿凭证 → 调后端 → 存 token」。凭证校验逻辑必须放在后端,前端不参与。 - 支付:统一为三步——前端向后端请求支付参数、调用各端支付 API 拉起收银台、后端接收异步回调并验签。前端只负责发起与结果提示,订单状态以后端回调为准,不能以客户端返回为准。
- 分享:各端的参数结构不同(标题、图片、路径的键名不一致),因此要封装成统一入参对象,再由网关按端转换,避免每个页面各写一套。
工程约束与验证方式
除隔离规则外,还有两条约束值得写进团队规范:一是新增端必须走网关,不允许在业务代码中直接判断平台;二是每次发版对三端做一轮冒烟,重点验证登录、支付、分享三条链路,因为这三处最容易在框架升级后出现行为漂移。
小结
多端适配的成本不在「写一次」,而在「差异隔离得是否干净」。把端差异收敛到少数几个文件、把关键链路的责任边界划清(前端负责发起、后端负责裁定),一套代码才能真正跑稳在多个端上,而不是每接一个端就重做一遍。