我有以下Vuex商店(main.js):
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//init store
const store = new Vuex.Store({
state: {
globalError: '',
user: {
authenticated: false
}
},
mutations: {
setGlobalError (state, error) {
state.globalError = error
}
}
})
//init app
const app = new Vue({
router: Router,
store,
template: '<app></app>',
components: { App }
}).$mount('#app')
我还为Vue路由器(routes.js)定义了以下路由:
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
//define routes
const routes = [
{ path: '/home', name: 'Home', component: Home },
{ path: '/login', name: 'Login', component: Login },
{ path: '/secret', name: 'Secret', component: SecretPage, meta: { requiresLogin: true }
]
我正在尝试这样做,如果Vuex存储了user
对象,并且它的authenticated
属性设置为false
,则路由器会将用户重定向到登录页面。
我有这个:
Router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresLogin) && ???) {
// set Vuex state's globalError, then redirect
next("/Login")
} else {
next()
}
})
问题是我不知道如何从beforeEach
函数内部访问Vuex商店的user
对象。
我知道我可以使用BeforeRouteEnter
在组件中使用路由器保护逻辑,但这会使每个组件变得混乱。我想在路由器级别集中定义它。
发布于 2021-02-11 03:46:09
您可以使用router.app
访问路由器注入的根Vue实例,然后通过router.app.$store
定期访问存储。
const router = new Router({
routes,
})
router.beforeEach((to, from, next) => {
// access store via `router.app.$store` here.
if (router.app.$store.getters('user')) next();
else next({ name: 'login' });
})
Vue 3
在Vue 3中删除了router.app
,但您仍可以按照migration guide中的说明在使用路由器时添加它
app.use(router)
router.app = app
发布于 2017-03-05 11:31:19
我最终将存储从main.js移到了store/index.js中,并将其导入到router.js文件中:
import store from './store'
//routes
const routes = [
{ path: '/home', name: 'Home', component: Home },
{ path: '/login', name: 'Login', component: Login },
{ path: '/secret', name: 'Secret', component: SecretPage, meta: { requiresLogin: true }
]
//guard clause
Router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresLogin) && store.state.user.authenticated == false) {
store.commit("setGlobalError", "You need to log in before you can perform this action.")
next("/Login")
} else {
next()
}
})
发布于 2020-06-19 21:27:38
当我使用guard router.beforeEach时,我发现商店在router.py中不可用,但是通过将guard更改为router.beforeResolve,商店就可用了。
我还发现,通过在guard router.beforeEach中等待商店的导入,我就能够成功地使用router.beforeEach了。我在下面的router.beforeResolve代码中提供了一个示例。
因此,为了使我的示例与OP的问题相似,下面是它如何为我工作的。我使用的是vue-router 3.0.2和vuex 3.1.0。
import Vue from 'vue'
import VueRouter from 'vue-router'
import store from '@/store'; //or use a full path to ./store
Vue.use(VueRouter)
//define routes
const routes = [
{ path: '/home', name: 'Home', component: Home },
{ path: '/login', name: 'Login', component: Login },
{ path: '/secret', name: 'Secret', component: SecretPage, meta: { requiresLogin: true }
]
const router = new VueRouter({
routes //es6
})
router.beforeResolve((to, from, next) => {
const user = store.state.user.user; //store with namespaced modules
if (to.matched.some(record => record.meta.requiresLogin) && user.isLoggedIn) {
next() //proceed to the route
} else next("/login") //redirect to login
})
export default router;
我还发现,通过在beforeEach守卫中等待存储的加载,我可以让router.beforeEach工作。
router.beforeEach(async (to, from, next) => {
const store = await import('@/store'); //await the store
const user = store.state.user.user; //store with namespaced modules
if (to.matched.some(record => record.meta.requiresLogin) && user.isLoggedIn) {
.... //and continue as above
});
https://stackoverflow.com/questions/42603909
复制相似问题