onLoad是页面级生命周期中唯一可靠获取路由参数的钩子,仅在页面实例创建后、DOM渲染前执行一次,参数来自URL query,需校验、兜底并避免操作未挂载DOM或未初始化data。

onLoad 是页面初始化时唯一能可靠获取路由参数的钩子,必须用在页面级生命周期中,不能用于组件或 App.vue。
onLoad 的触发时机和参数来源
它在页面实例创建后、DOM 渲染前立即执行,此时 options 已解码并注入,但 this.data 可能还未完成响应式代理(尤其在 Vue 3 setup 模式下需注意)。
-
onLoad只触发一次,哪怕用户多次返回该页面(比如从详情页 → 购物车 → 再返回详情页) - 参数来自 URL query,例如跳转链接是
/pages/product/detail?id=123&from=search,则options.id === "123"、options.from === "search" - H5 平台下,若通过浏览器地址栏直接访问,
options为空对象,需兜底处理
常见错误:在 onLoad 里操作 DOM 或 this.data 失效
因为 DOM 尚未挂载,且 Vue 实例可能未完全初始化,直接调用 this.$refs.xxx 或给 this.data.xxx 赋值常导致 undefined 或视图不更新。
- 不要在
onLoad中使用uni.createVideoContext或uni.createCanvasContext—— 改用onReady - 不要直接写
this.product = res.data(尤其 Vue 2 选项式),应改用this.$set(this, 'product', res.data)或确保 data 已声明字段 - 在
setup+ref场景下,可安全赋值,但需确认 ref 已在data()或setup()中正确定义
正确用法:加载数据 + 参数校验 + 条件跳转
这是最典型的实战组合,兼顾性能与健壮性:
export default {
data() {
return {
product: null,
loading: true
}
},
onLoad(options) {
// 1. 参数校验(避免空 ID 导致 404)
if (!options.id) {
uni.showToast({ title: '参数错误', icon: 'none' })
uni.navigateBack()
return
}
// 2. 发起请求(异步不阻塞 UI)
this.fetchProduct(options.id)
},
methods: {
async fetchProduct(id) {
try {
const res = await uni.request({
url: `/api/products/${id}`
})
this.product = res.data
} catch (err) {
uni.showToast({ title: '加载失败', icon: 'none' })
} finally {
this.loading = false
}
}
}
}
注意:uni.request 在子线程执行,不影响主线程渲染,所以放在 onLoad 完全合理;但若请求逻辑复杂(如带缓存策略、鉴权重试),建议封装成独立 service 函数,而非堆在钩子里。
跨端差异:H5 和小程序传参方式不同
微信小程序支持 uni.navigateTo 的 events 通信,但 onLoad 仍只收 query;H5 则完全依赖 URL search 参数。更隐蔽的问题是:
- App 端(iOS/Android)对中文或特殊字符的 query 解码更严格,建议服务端统一用
encodeURIComponent编码,前端onLoad直接用即可 - 如果用
uni.reLaunch带参数跳转,部分 Android 机型会丢失options,应改用uni.navigateTo+uni.setStorageSync临时存参作为 fallback - 条件编译时,H5 下无法监听“后台切回”,但
onLoad不受影响 —— 它只管首次加载
真正容易被忽略的是:onLoad 执行时,store 或 globalData 可能尚未就绪(尤其在 onLaunch 异步初始化未完成时),别在 onLoad 里直接读取未保证初始化的全局状态。










