首页 文章

定义Vue-Router路由时访问Vuex状态

提问于
浏览
14

我有以下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-Router(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 }
]

我'm trying to make it so that if the Vuex store' s user 对象有 authenticated 属性为false,让路由器将用户重定向到Login页面 .

我有这个:

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函数中没有't know how to access the Vuex store' s user 对象 .

我知道我可以使用 BeforeRouteEnter 在组件内部使用路由器保护逻辑,但这会使每个组件混乱 . 我想在路由器级别集中定义它 .

4 回答

  • 15

    正如here建议的那样,您可以做的是从您所在的文件中导出您的商店并将其导入 routes.js . 它将类似于以下内容:

    你有一个 store.js

    import Vuex from 'vuex'
    
    //init store
    const store = new Vuex.Store({
        state: {
            globalError: '',
            user: {
                authenticated: false
            }
         },
         mutations: {
             setGlobalError (state, error) {
                 state.globalError = error
             }
         }
    })
    
    export default store
    

    现在 routes.js ,您可以:

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import store from ./store.js
    
    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 }
    ]
    
    Router.beforeEach((to, from, next) => {
        if (to.matched.some(record => record.meta.requiresLogin) && ???) {
            // You can use store variable here to access globalError or commit mutation 
            next("/Login")
        } else {
            next()
        }
    })
    

    main.js 中您也可以导入 store

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    import store from './store.js'
    
    //init app
    const app = new Vue({
        router: Router,
        store,
        template: '<app></app>',
        components: { App }
    }).$mount('#app')
    
  • 0

    我最终将商店从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()
        }
    })
    
  • 0

    这就是我想要的 .

    在App.vue中,我将在cookie上保存一个存储身份验证详细信息的观察程序 . (显然我会在身份验证后将包含身份验证详细信息的令牌存储为cookie)

    现在每当这个cookie变空时,我都会将用户路由到/ login页面 . 注销会删除cookie . 现在,如果用户在注销后回击,现在由于cookie不存在(需要用户登录),用户将被路由到登录页面 .

  • 1

    管理您的位置状态与其他应用程序状态分开可能会使这样的事情变得比他们可能需要的更难 . 在处理Redux和Vuex中的类似问题后,我开始使用 router 模块管理我的Vuex存储中的位置状态 . 您可能想要考虑使用该方法 .

    在您的特定情况下,您可以查看Vuex商店本身内的位置何时发生变化,并调度相应的“重定向”操作,如下所示:

    dispatch("router/push", {path: "/login"})
    

    比起您认为将位置状态作为Vuex模块进行管理更容易 . 如果你想尝试一下,你可以使用我的作为起点:

    https://github.com/geekytime/vuex-router

相关问题