vue3 如何让 beforeEach 钩子里异步事件执行完之后执行 onMounted 里的异步事件?
如题,我的需求是实现 app 内无感免登。
用户认证信息会半天失效。
beforeEach 钩子里会先判断认证信息有没有失效,失效情况下请求免登接口再跳转到 list 路由;有效情况下直接跳转到 list 路由
登录失效的几个场景
- 打开应用,缓存的认证失效
- 切换路由,认证失效
- 当前页面请求数据,认证失效
我现在遇到的问题是,没法等待 beforeEach 里的免登请求获取到认证信息后,再执行业务组件 A里 onMounted 的请求,这样的话会导致 onMounted 里的请求,携带的认证信息是失效的,接口会报401错误。
具体的业务逻辑:打开应用, 路由是 /
, 会重定向到列表页 /list
,这时候是能先执行完 beforeEach 里的免登接口再执行 list 组件里的异步事件
当认证失效情况下,从列表页 /list
到详情页/detial
,就没法先执行完 beforeEach 的免登接口后再执行 onMounted 里的异步事件了,导致了 401 报错。
几处逻辑代码
// 路由钩子里router.beforeEach(async (to) => {
// 判断 认证是否失效
const isLogin = await Store.dispatch('login/checkTokenEffective')
if (!isLogin) {
// 失效情况下请求免登接口
Store.dispatch('login/handleLoginAction', to.path)
} else if(to.path === '/') {
return { name: 'LIST' }
}
})
// vuex action
async handleLoginAction({ dispatch }, path='/list') {
// 免登请求
await dispatch('ddFreeLogin')
// 2. 登录成功后的响应
await dispatch('getDetailsAfterSuccessLogin')
// 3. 进入列表页
if(path === '/') {
await router.push('/list')
}
}
// list 组件里
onMounted(() => {
getList()
})
另外,感觉我这样设计路由不是很合理。认证失效情况下执行免登,免登成功后请求用户数据再跳转路由;但是当认证成功的情况下,路由切换不需要请求用户数据。目前请求用户数据的逻辑我是放到了main.js 中,用于刷新页面的时候请求。不过感觉这样并不太优雅。
期待您的回答,十分感谢。
回答:
这个路由守卫有回调函数有三个参数,最后一个就是去向目标路由
router.beforeEach(function (to, from , next) { setTimeout(function () {
next('') // 即将跳转到的路由
}, 3000)
})
回答:
在执行免登后,路由钩子需要有 return true
这样就能先执行路由钩子的异步事件,再执行业务组件里的异步事件了
router.beforeEach(async (to) => { const isLogin = await Store.dispatch('login/checkTokenEffective')
if (!isLogin) {
await Store.dispatch('login/handleLoginAction', to.path)
return true // 这一步很关键
} else if(to.path === '/') {
return { name: 'LIST' }
}
})
以上是 vue3 如何让 beforeEach 钩子里异步事件执行完之后执行 onMounted 里的异步事件? 的全部内容, 来源链接: utcz.com/p/933127.html