微信小程序和 H5 的 API 差异客观存在:小程序靠 wx.login 拿 code,H5 通常用设备号或账号密码;小程序能直接调扫码,H5 只能跳转链接。条件编译是 UniApp 官方推荐的解法:编译器按平台裁剪代码,一套源码多处发布。
实现思路
以 // #ifdef 与 // #ifndef 包裹差异代码块,后面跟上平台标识 MP-WEIXIN 表示微信小程序、H5 表示网页端;同一业务函数里写两套实现,各自调用对应平台 API,编译时只保留当前平台分支。
登录差异处理
// utils/auth.js
export function login() {
// #ifdef MP-WEIXIN
uni.login({
provider: "weixin",
success: async (res) => {
const data = await http.post("/auth/wechat-login", {
code: res.code
});
saveToken(data);
}
});
// #endif
// #ifdef H5
const deviceId = getDeviceId(); // 取浏览器指纹
http.post("/auth/guest-login", { deviceId }).then((data) => {
saveToken(data);
});
// #endif
}
扫码降级
小程序用 uni.scanCode 直接调起摄像头,H5 不支持该能力,改为引导用户输入码或复制链接。
export function scanCode() {
// #ifdef MP-WEIXIN
uni.scanCode({
success: (res) => handleCode(res.result),
fail: () => uni.showToast({ title: "扫码失败", icon: "none" })
});
// #endif
// #ifdef H5
uni.showModal({
title: "提示",
content: "当前浏览器不支持扫码,请输入桌台码",
editable: true,
success: (r) => {
if (r.confirm && r.content) handleCode(r.content.trim());
}
});
// #endif
}
模板里的条件编译
条件编译同样适用于 template 与 css,例如 H5 顶部做沉浸式适配、小程序显示胶囊占位。
// template 内写法
// #ifdef H5
<view class="status-bar"></view>
// #endif
// #ifdef MP-WEIXIN
<view class="nav-capsule">自定义导航</view>
// #endif
/* style 内写法 */
/* #ifdef H5 */
.page { padding-top: 44px; }
/* #endif */
封装统一出口
为避免页面到处写 #ifdef,把平台差异收敛到 utils 层统一导出,业务页面只调用同名字段。
// utils/platform.js
export const isMp = () => {
// #ifdef MP-WEIXIN
return true;
// #endif
// #ifndef MP-WEIXIN
return false;
// #endif
};
需要注意
- 条件编译写在注释里,// #ifdef 前必须有双斜杠且保持固定写法,关键字不能被变量拼接;
- 模板与样式里的条件编译用 HTML 注释 / CSS 注释包住,写法不同不要混用;
- 条件编译是在编译期裁剪,无法在运行时切换平台,调试时需分别运行到各端预览;
- 真机上验证微信登录,需要在微信公众平台配置业务域名与 AppSecret。
小结
条件编译是 UniApp 跨端开发的核心武器,把差异点收口在工具层,业务代码保持平台无关,两端的维护成本基本趋近于一套。
评论(0)
暂无评论,快来抢沙发吧~