Vue初始化路由前校验localStorage token 避免默认路由组件提前加载问题
解决方案
方案1:优先使用路由全局前置守卫(最推荐)
直接把校验逻辑从App组件的created钩子移到路由全局前置守卫beforeEach中,所有路由跳转都会先触发该钩子,等校验逻辑执行完成后再决定放行的目标路由,从根源避免错误组件提前渲染的问题。
示例代码:
// router/index.js (Vue3写法,Vue2逻辑完全一致) import { createRouter, createWebHistory } from 'vue-router' const router = createRouter({ history: createWebHistory(), routes: [/* 你的路由配置 */] }) let initChecked = false // 标记初始化校验是否完成,避免每次路由跳转重复发请求 router.beforeEach(async (to, from, next) => { if (initChecked) { next() return } // 执行你的校验逻辑 const localValid = checkLocalStorage() // 本地localStorage校验逻辑 const serverValid = await fetchServerAuth() // 服务端校验异步请求 initChecked = true if (localValid && serverValid) { // 校验通过,如果访问的是根路径就跳业务页,否则跳用户原本要访问的地址 next(to.path === '/'? '/dashboard' : to.fullPath) } else { next('/login') } })
方案2:保留App组件内逻辑的情况下加渲染开关
如果一定要把校验逻辑放在App组件内,可以加一个状态控制路由视图的渲染,校验完成前只显示加载态,不渲染任何路由组件。
示例代码:
<!-- App.vue --> <template> <div v-if="!checkDone" class="init-loading">应用初始化中...</div> <router-view v-else /> </template> <script> export default { data() { return { checkDone: false } }, async created() { try { // 执行你的校验逻辑 const localValid = checkLocalStorage() const serverValid = await fetchServerAuth() this.checkDone = true // 校验完成后执行路由跳转 if (localValid && serverValid) { this.$router.replace('/dashboard') } else { this.$router.replace('/login') } } catch (e) { // 加异常捕获避免接口报错卡住 this.checkDone = true this.$router.replace('/login') } } } </script>
注意事项
- 所有异步校验逻辑必须加错误捕获,避免接口异常导致页面一直卡在加载态
- 校验逻辑只需要在应用首次加载时执行一次,记得加状态标记避免重复发起服务端请求
内容的提问来源于stack exchange,提问作者Joshua Ohana
相关产品推荐
相关产品推荐

