Javascript 定义 Vue-Router 路由时访问 Vuex 状态
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42603909/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Accessing Vuex state when defining Vue-Router routes
提问by Ege Ersoz
I have the following Vuex store (main.js):
我有以下 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')
I also have the following routes defined for Vue-Router (routes.js):
我还为 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 }
]
I'm trying to make it so that if the Vuex store's userobject has authenticatedproperty false, have the router redirect the user to the Login page.
我试图做到这一点,如果 Vuex 商店的user对象具有authenticated属性 false,则让路由器将用户重定向到登录页面。
I have this:
我有这个:
Router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresLogin) && ???) {
// set Vuex state's globalError, then redirect
next("/Login")
} else {
next()
}
})
The problem is I don't know how to access the Vuex store's userobject from inside the beforeEach function.
问题是我不知道如何user从 beforeEach 函数内部访问 Vuex 商店的对象。
I know that I can have the router guard logic inside components using BeforeRouteEnter, but that would clutter up each component. I want to define it centrally at the router level instead.
我知道我可以在组件内部使用路由器保护逻辑BeforeRouteEnter,但这会使每个组件变得混乱。我想在路由器级别集中定义它。
回答by Saurabh
As suggested here, what you can do is to export your store from the file it is in and import it in the routes.js. It will be something like following:
正如此处所建议的,您可以做的是从商店所在的文件中导出商店并将其导入到routes.js 中。它将类似于以下内容:
You have one store.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
Now in routes.js, you can have:
现在在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()
}
})
In main.jsalso you can import store:
在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')
回答by Chris Jaynes
Managing your location state separate from the rest of your application state can make things like this harder than they maybe need to be. After dealing with similar problems in both Redux and Vuex, I started managing my location state insidemy Vuex store, using a routermodule. You might want to think about using that approach.
将您的位置状态与应用程序状态的其余部分分开管理可能会使这样的事情比他们可能需要的更难。处理在这两个终极版和Vuex类似问题后,我开始管理我的位置状态里面我Vuex店,使用router模块。您可能想考虑使用这种方法。
In your specific case, you could watch for when the location changes within the Vuex store itself, and dispatch the appropriate "redirect" action, like this:
在您的特定情况下,您可以观察 Vuex 存储本身内的位置何时发生变化,并分派适当的“重定向”操作,如下所示:
dispatch("router/push", {path: "/login"})
It's easier than you might think to manage the location state as a Vuex module. You can use mine as a starting point if you want to try it out:
将位置状态作为 Vuex 模块进行管理比您想象的要容易。如果您想尝试一下,可以使用我的作为起点:
回答by Ege Ersoz
I ended up moving the store out of main.js and into store/index.js, and importing it into the router.js file:
我最终将 store 从 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()
}
})
回答by chirag jain
This is how i would to it.
这就是我想要的方式。
In App.vue, I will keep a watcher on cookie that stores authentication details. ( Obviously I would store a token containing authentication details as cookie after authentication )
在 App.vue 中,我将在存储身份验证详细信息的 cookie 上保持观察者。(显然我会在身份验证后将包含身份验证详细信息的令牌存储为 cookie)
Now whenever this cookie becomes empty, I will route the user to /login page. Logging out deletes the cookie. Now if user hit back after logging out, now since the cookie doesnot exist, ( which requires user to be logged in ), user will be routed to login page.
现在,每当此 cookie 变空时,我都会将用户路由到 /login 页面。注销会删除 cookie。现在,如果用户在注销后回击,现在由于 cookie 不存在(需要用户登录),用户将被路由到登录页面。

