Quasar路由beforeEnter重定向后Vuex commit抛出mutation外修改状态错误问询
问题根因
报错是两个错误写法共同触发的:
- Vuex user模块的state是顶层固定对象,所有store实例会共用同一份state引用
- Quasar导出的store是工厂函数,你在路由守卫中每次调用
store()都会生成新的store实例,和Vue组件绑定的实例不是同一个
触发报错的完整逻辑:
当你直接访问/dashboard时,路由守卫先调用store()生成第一个实例,开启严格模式后会监听共享state的所有修改。后续Vue应用初始化时会生成第二个store实例绑定到组件,你登录时触发第二个实例的mutation修改共享state,第一个实例的监听器检测到state不是通过自身mutation修改,就会抛出错误。
如果没有先触发路由守卫(比如直接访问/login再登录),全程只有组件绑定的一个store实例,就不会报错,完全符合你遇到的场景。
修复步骤
1. 将Vuex模块的state改为工厂函数
修改src/store/user.js的state定义,保证每个store实例有独立的state:
// 把原来的固定对象改成返回对象的函数 const state = () => ({ token: null, user:{ username: null } }) // 其余getters、mutations、actions代码保持不变
2. 路由中缓存store实例,避免重复创建
修改src/routes.js,缓存store实例保证全局唯一,同时修正登录页重定向路径:
import store from 'src/store' // 缓存store实例,全局仅创建一次 let storeInstance = null const getStore = () => { if(!storeInstance) storeInstance = store() return storeInstance } const routes = [ { path: '/', component: () => import('layouts/MainLayout.vue'), children: [ { path: '', component: () => import('pages/Home.vue') }, { path: '/login', component: () => import('pages/Login.vue') }, { path: '/dashboard', component: () => import('pages/Dashboard.vue'), beforeEnter: (to, from, next) => { const authenticated = getStore().getters['user/authenticated'] console.log(authenticated) if(authenticated){ return next() } next('/login') } }, ] }, { path: '/:catchAll(.*)*', component: () => import('pages/Error404.vue') } ] export default routes
内容的提问来源于stack exchange,提问作者Prasanga Thapaliya
相关产品推荐
相关产品推荐

