AdminLTE3 Preloader配合Laravel Sanctum+VueJS前置鉴权时卡死问题
问题描述
我当前使用的技术栈为:VueJS 2、Laravel 8、Laravel Sanctum、Laravel Mix,需要在用户进入页面前完成身份鉴权校验。参考Stack Overflow相关回答实现鉴权逻辑后,AdminLTE3的Preloader预加载器出现卡死现象,站点无法正常加载。
相关代码
Vuex Store 代码
const store = new Vuex.Store({ state:{ user: false, isCheckedAuth: false }, mutations:{ auth(state, payload){ state.user=payload; state.isCheckedAuth = true; } }, getters:{ isAuth(state){ if(!state.user) return false; else return true; }, getNameInitials(state){ return `${state.user.last_name} ${state.user.first_name[0]}. ${state.user.middle_name[0]}.`; }, hasPermission(state){ return function (needPermission){ if(state.user.permissions.find(permission => permission === needPermission)) return true; else return false; } }, isCheckedAuth(state){ return state.isCheckedAuth; } }, actions:{ async checkAuth(){ return await axios.get('/api/v.1.0/user').then(r=>{ store.commit('auth',r.data.data) }) } } })
原Vue实例初始化代码(触发预加载卡死)
const VueInstance = ()=>{ new Vue({ el: "#app", router, store, components: { App } }) } store.dispatch('checkAuth').then(() => { VueInstance(); }).catch(() => { VueInstance(); })
可正常运行的初始化代码(无法实现提前鉴权)
new Vue({ el: "#app", router, store, components: { App } })
故障根因
AdminLTE3的预加载器默认会在页面DOM加载完成、前端脚本初始化完成后自动隐藏。你原写法会等待鉴权接口返回后才初始化Vue实例并挂载到#app节点,AdminLTE3的初始化逻辑执行时找不到对应节点、等待Vue挂载超时,就会出现预加载器持续显示的卡死现象。
修复方案
不要延迟Vue实例的初始化,改为用路由全局守卫配合isCheckedAuth状态实现进入页面前的鉴权,同时兼容预加载器的正常隐藏逻辑:
- 保留直接初始化Vue实例的写法,同时通过路由守卫在所有页面跳转前先执行鉴权校验
- 鉴权未完成时先挂起路由跳转,等鉴权结果返回后再根据登录状态判断是放行还是跳转到登录页,同样能达到进入页面前完成鉴权的需求
- 可手动控制预加载器的显隐,避免自动隐藏逻辑失效
修正后代码示例
新增路由全局守卫
router.beforeEach(async (to, from, next) => { // 未完成鉴权时先执行鉴权请求 if (!store.getters.isCheckedAuth) { try { await store.dispatch('checkAuth') } catch (e) { // 鉴权失败重置用户状态 store.commit('auth', false) } } // 按需判断路由是否需要登录权限 const requiresAuth = to.meta.requiresAuth ?? true if (requiresAuth && !store.getters.isAuth) { return next({ name: 'Login' }) } next() })
修正后的Vue初始化代码
new Vue({ el: "#app", router, store, components: { App }, // 手动控制预加载器隐藏,兼容原有逻辑 mounted() { const preloader = document.querySelector('.preloader') preloader && preloader.remove() } })
内容的提问来源于stack exchange,提问作者Andrew Stetsko
相关产品推荐
相关产品推荐

