求助:index.js中读取LocalStorage的authUser对象时常返回null
这个报错的核心原因其实很明确:你在路由配置外层一次性读取了localStorage的authUser,但这个读取操作是在项目初始化阶段就执行的,而authUser是用户登录后才写入localStorage的。
举个例子:当你刚打开项目时,index.js里的const authUser = JSON.parse(window.localStorage.getItem('authUser'))就已经执行了,这时候localStorage里根本没有这个值,所以authUser是null。哪怕之后用户登录成功写入了authUser,这个外层的authUser变量也不会自动更新——它还是初始化时的null值,这就导致beforeEnter钩子判断时触发Cannot read property 'role' of null的错误。
另外还有一种小概率情况:登录时的localStorage.setItem虽然是同步操作,但某些场景下可能存在写入延迟,紧接着的$router.push可能在写入完成前就触发了路由守卫,这也会导致读取到null。
修复步骤
把localStorage读取逻辑移到
beforeEnter钩子内部
不要在路由配置外层提前读取,而是每次进入路由时实时读取,这样能拿到最新的localStorage值,同时还要先判断authUser是否存在,避免null报错:{ path: '/admin', component: Sidebar, beforeEnter: (to, from, next) => { // 每次进入路由时才读取localStorage const authUser = JSON.parse(window.localStorage.getItem('authUser')); var roleshash = { 1: 'admin', 2: 'doctor', 3: 'receptionist', 4: 'patient' } // 先判断authUser是否存在,避免null报错 if (!authUser) { Swal.fire({ type: 'error', title: 'Access Denied!', text: 'Please log in first' }); next({ path: '/' }); return; } if (authUser.role === 1) { next(); } else { Swal.fire({ type: 'error', title: 'Access Denied!', text: 'Unauthorized access occured' }); next({ path: '/' + roleshash[authUser.role] }); } } }优化登录时的写入逻辑(可选)
虽然localStorage.setItem是同步的,但为了避免极端情况下的时序问题,可以稍微延迟路由跳转,确保写入完成后再跳转:if(response.body.role === '1'){ authUser.id = response.body.id authUser.email = response.body.email authUser.role = 1 window.localStorage.setItem('authUser', JSON.stringify(authUser)); // 加个微小的延迟,确保写入完成 setTimeout(() => { self.$router.push({path: 'admin'}); }, 100); }全局路由守卫的优化建议(可选)
如果你的项目里多个路由都需要权限校验,建议把权限逻辑抽成全局的路由守卫(比如router.beforeEach),这样不用每个路由都写重复代码,也能更统一地处理未登录、权限不足的情况。
内容的提问来源于stack exchange,提问作者Ajmal-Hossain

