uniapp中onLaunch异步方法与onLoad执行顺序问题

app.vue 里的 onLaunch 中如果有异步方法,比如登录方法,返回结果可能会在页面的 onLoad 之后,想让页面的 onLoad 在 onLaunch 之后执行。

解决

场景:比如微信小程序在 onLaunch 中进行登录后取得 openid 并获得 token,项目各页面需要带上该 token 请求其他接口。

vue2

main.js

1
2
3
Vue.prototype.$onLaunched = new Promise((resolve) => {
Vue.prototype.$isResolve = resolve
})

App.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<script>
export default {
onLaunch() {
/**
* 可以setTimeout()模拟异步,观察执行顺序
* ------
*/
// #ifndef H5
uni.login({
success: (loginRes) => {
// #ifdef MP-WEIXIN
login({
// 该接口为我们自己写的获取 openid/token 的接口,请替换成自己的
appId: 'wx1234567890',
code: loginRes.code
}).then((res) => {
try {
console.info(res.object.token)
uni.setStorageSync('mcToken', res.object.token)
this.$isResolve()
} catch (e) {
console.error(e)
}
})
// #endif
}
})
// #endif
}
}
</script>

页面 onLoad

1
2
3
4
5
6
7
8
9
<script>
export default {
async onLoad(option) {
// 等待登录成功
await this.$onLaunched
// 后续业务逻辑
}
}
</script>

vue3

main.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// #ifdef VUE3
import { createSSRApp } from 'vue'
import App from './App.vue'

export function createApp() {
const app = createSSRApp(App)
app.config.globalProperties.$onLaunched = new Promise((resolve) => {
app.config.globalProperties.$isResolve = resolve
})
return {
app
}
}
// #endif

App.vue

1
2
3
4
5
6
7
8
9
10
<script>
export default {
onLaunch: function () {
setTimeout(() => {
console.log('--App-onLaunch', this)
this.$isResolve()
}, 2000)
}
}
</script>

页面 onLoad

1
2
3
4
5
6
7
8
9
10
<script>
export default {
async onLoad() {
await this.$onLaunched
setTimeout(() => {
console.log('--page-onLoad', this)
}, 1000)
}
}
</script>

相关链接

[1] app.onLaunch 与 page.onLoad 异步问题终极解决方案

[2] vue 官网-app.config.globalProperties