直接回答:uni-app 的难点不在 API 本身,而在于同一套代码要在三个差别很大的运行环境里跑。开发时心里要一直有两根弦:一是生命周期在什么时候执行(尤其是 onLoad 和 onShow 的次数差别),二是这段代码在小程序、H5、App 上分别是什么行为。条件编译就是用来处理后者差异的。

应用生命周期与页面生命周期

应用级(写在 App.vue 里):

钩子 触发时机 注意
onLaunch 应用初始化完成,全局只触发一次 适合做登录态检查、全局配置初始化,不要在这里做必须等待的异步
onShow 启动或从后台切回前台 每次切前台都会触发
onHide 从前台进入后台 适合保存临时状态
onError 应用报错 可以用来上报

页面级(写在页面组件里):

钩子 触发时机
onLoad 页面加载,一个页面只执行一次,能拿到上个页面传来的参数
onShow 每次显示都执行,包括从别的页面返回
onReady 首次渲染完成,可以安全操作 DOM 类内容
onHide / onUnload 页面隐藏 / 卸载
onPullDownRefresh / onReachBottom 下拉刷新 / 触底加载
onShareAppMessage 分享(小程序、App)

两个最容易踩的坑:

  1. onLoad 只执行一次,onShow 每次都执行。 在 onLoad 里请求数据,从详情页返回列表页时列表不会刷新;想刷新就得把逻辑放到 onShow 里。
  2. 页面栈有层数限制。 小程序默认最多 10 层,navigateTo 超过就跳不动了。层级深的时候要用 redirectTo 或 reLaunch 换掉当前页,而不是一味地压栈。

页面之间怎么传参

方式一:URL 参数(最常用)

1
2
3
4
5
6
uni.navigateTo({ url: '/pages/detail/detail?id=12&type=order' });

// 目标页
onLoad(options) {
console.log(options.id, options.type); // 都是字符串
}

值只能是字符串,传对象要自己 encodeURIComponent(JSON.stringify(obj)),注意 URL 长度限制。

方式二:事件通道(适合传对象)

1
2
3
4
5
6
7
8
9
10
uni.navigateTo({
url: '/pages/detail/detail',
success: (res) => res.eventChannel.emit('detail', { id: 12 })
});

// 目标页
onLoad() {
const channel = this.getOpenerEventChannel();
channel.on('detail', (data) => { this.detail = data; });
}

方式三:全局事件或状态,适合跨多层、非父子关系的通信:

1
2
3
uni.$emit('refresh-list');
uni.$on('refresh-list', handler);
// 别忘了在 onUnload 里 uni.$off,否则会重复注册

选择建议:简单字段用 URL 参数;对象用事件通道;跨页面广播用 uni.$emit,但一定要记得取消订阅。

条件编译:一套代码适配三端

用注释包裹的写法,只在对应平台参与编译:

1
2
3
4
5
6
7
// #ifdef MP-WEIXIN
wx.login({ success: (res) => { /* 微信小程序特有 */ } });
// #endif

// #ifndef H5
plus.screen.lockOrientation('portrait-primary'); // App 端锁屏
// #endif

常见平台标识:MP-WEIXIN(微信小程序)、MP-ALIPAY、H5、APP-PLUS、APP-ANDROID、APP-IOS。CSS 和模板里也能用,写法略有不同(<!-- #ifdef --> 和 /* #ifdef */)。

一个经验:条件编译要集中,不要撒得满地都是。同一个平台差异最好收在一个函数里,外面留统一的接口,否则半年后没人敢改这段代码。

三端最容易踩的差异

差异点 说明
尺寸单位 用 rpx 自适应,设计稿按 750px 宽出图;但字体大小用 px 更可控
导航栏 H5 没有原生导航栏,小程序和 App 有;自定义导航栏要三端分别测
滚动 页面级滚动和小程序里 scroll-view 的行为不同,scroll-view 必须给固定高度
组件限制 小程序对部分 CSS 选择器、动态组件支持有限,v-html 也不支持
图片 小程序的 image 组件有默认尺寸,不写宽高可能不显示
接口域名 小程序请求的域名必须在后台白名单里,且必须是 HTTPS
包体积 微信小程序主包 2MB 限制,超了要分包,依赖库要精挑

Vue 2 和 Vue 3 的差异也要注意:Vue 3 版本才支持 Composition API 和 <script setup>,一些老项目依赖的插件在两个版本间并不通用。

调试与发布上的提醒

  1. 真机调试是必须的,模拟器上的表现和真机差距很大,尤其是滚动、键盘弹出和定位;
  2. manifest.json 里的 AppID、权限、图标、启动图,各平台都要单独配;
  3. 小程序每次发版要走平台审核,紧急修 bug 也得上线审核,所以关键逻辑要有远端开关;
  4. pages.json 里的页面顺序会影响启动页,别把调试页留在第一位。

本文整理自我自己早先记录的 uni-app 笔记(原始素材以官方文档的 API 对照表为主),这里按开发中真正会遇到的顺序重新组织,并补充了跨端差异与调试经验,文字由 AI 协助改写后经我复核。API 细节以 uni-app 官方文档和所用版本为准。

这篇笔记整理自我自己的实践记录,如果做法有出入,或者你踩过别的坑,欢迎到留言板一起聊聊。

站内搜索

没有找到内容!