在 Vue 路由解析之前访问 Vuex
Access Vuex before Vue route is resolved
我有什么:
- 具有需要身份验证的路由和 public 路由的路由器
- 具有用户身份验证状态的 vuex
我想要什么:使用 axios
向服务器发送请求以检查用户的身份验证状态 before 应用已加载(在解决路由器之前)。
router.js
:
import Vue from 'vue'
import Router from 'vue-router'
import store from './store'
Vue.use(Router)
const router = new Router({
...
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/account',
name: 'account',
component: () => import(/* webpackChunkName: "account" */ './views/Account.vue'),
meta: {
requiresAuth: true
}
}
]
})
router.beforeEach((to, from, next) => {
if (to.matched.some(route => route.meta.requiresAuth)) {
if (store.state.authStatus)
next()
else
next({name: 'home'})
} else {
next()
}
})
export default router
store.js
:
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
authStatus: false
},
mutations: {
setAuthStatus(state, authStatus) {
state.authStatus = authStatus
}
}
})
axios.get(...)
.then(response => {
store.commit('setAuthStatus', true)
})
export default store
main.js
:
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
我的问题:当我在浏览器中输入 mydomain.com/acount
时(应用程序之前未加载)在被授权时,无论如何我都被重定向到 home
。重定向后,我看到我已获得授权(我在 Home 组件中设置了一些 DOM 元素,该元素仅对授权用户显示)。
我试过了,没用:
store.js
:
const store = new Vuex.Store({
...
actions: {
setAuthStatus({commit}) {
axios.get(...)
.then(response => {
commit('setAuthStatus', true)
})
}
}
})
main.js
:
store.dispatch('setAuthStatus').then(() => {
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
})
编辑:在 main.js
我试图从
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
至
new Vue({
store,
router,
render: h => h(App)
}).$mount('#app')
它也没有帮助。
在 navigation guard 中你需要一些异步的东西所以在商店中保存你的 axios promise 作为 authStatus。当它解决提交并设置登录状态时。
在navigation guard等待promise resolve然后调用next函数进入下一个router
Store.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
/* EXAMPLE
authStatus: new Promise(resolve => {
setTimeout(() => {
const requestResult = true;
store.commit("setAuthStatus", requestResult);
resolve(requestResult);
}, 1000);
}),
*/
authStatus: axios.get(...).then((requestResult) => {
store.commit("setAuthStatus", requestResult);
}),
loggedIn: false
},
mutations: {
setAuthStatus(state, loggedIn) {
state.loggedIn = loggedIn;
}
}
});
export default store;
router.js
router.beforeEach((to, from, next) => {
if (to.matched.some(route => route.meta.requiresAuth)) {
store.state.authStatus.then(loggedIn => {
if (loggedIn) next();
else next({ name: "home" });
});
} else {
next();
}
});
检查此解决方案是否有效 here
问题可能是因为当您输入 url
https://example.com/account
它启动应用程序,axios 向服务器执行异步请求。
所以也许你应该尝试从 beforeEach 中进行 axios 调用。
通过这种方式,您可以毫无问题地验证用户。
问题是你不能使 axios 同步,所以你必须 return 与 axios 的承诺才能实现功能。
请告诉我这是否对您有帮助。
兜兜转转,我接下来的问题就解决了。
store.js
:
const store = new Vuex.Store({
state: {
authStatus: axios.get(...).then(response => {
store.commit('setAuthStatus', true)
}),
userAuth: false
},
mutations: {
setAuthStatus(state, authStatus) {
state.userAuth = authStatus
}
}
})
router.js
:
router.beforeEach((to, from, next) => {
if (to.matched.some(route => route.meta.requiresAuth)) {
store.state.authStatus.then(() => {
//we're getting 200 status code response here, so user is authorized
//be sure that API you're consuming return correct status code when user is authorized
next()
}).catch(() => {
//we're getting anything but not 200 status code response here, so user is not authorized
next({name: 'home'})
})
} else {
next()
}
})
我有什么:
- 具有需要身份验证的路由和 public 路由的路由器
- 具有用户身份验证状态的 vuex
我想要什么:使用 axios
向服务器发送请求以检查用户的身份验证状态 before 应用已加载(在解决路由器之前)。
router.js
:
import Vue from 'vue'
import Router from 'vue-router'
import store from './store'
Vue.use(Router)
const router = new Router({
...
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/account',
name: 'account',
component: () => import(/* webpackChunkName: "account" */ './views/Account.vue'),
meta: {
requiresAuth: true
}
}
]
})
router.beforeEach((to, from, next) => {
if (to.matched.some(route => route.meta.requiresAuth)) {
if (store.state.authStatus)
next()
else
next({name: 'home'})
} else {
next()
}
})
export default router
store.js
:
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
authStatus: false
},
mutations: {
setAuthStatus(state, authStatus) {
state.authStatus = authStatus
}
}
})
axios.get(...)
.then(response => {
store.commit('setAuthStatus', true)
})
export default store
main.js
:
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
我的问题:当我在浏览器中输入 mydomain.com/acount
时(应用程序之前未加载)在被授权时,无论如何我都被重定向到 home
。重定向后,我看到我已获得授权(我在 Home 组件中设置了一些 DOM 元素,该元素仅对授权用户显示)。
我试过了,没用:
store.js
:
const store = new Vuex.Store({
...
actions: {
setAuthStatus({commit}) {
axios.get(...)
.then(response => {
commit('setAuthStatus', true)
})
}
}
})
main.js
:
store.dispatch('setAuthStatus').then(() => {
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
})
编辑:在 main.js
我试图从
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
至
new Vue({
store,
router,
render: h => h(App)
}).$mount('#app')
它也没有帮助。
在 navigation guard 中你需要一些异步的东西所以在商店中保存你的 axios promise 作为 authStatus。当它解决提交并设置登录状态时。 在navigation guard等待promise resolve然后调用next函数进入下一个router
Store.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
/* EXAMPLE
authStatus: new Promise(resolve => {
setTimeout(() => {
const requestResult = true;
store.commit("setAuthStatus", requestResult);
resolve(requestResult);
}, 1000);
}),
*/
authStatus: axios.get(...).then((requestResult) => {
store.commit("setAuthStatus", requestResult);
}),
loggedIn: false
},
mutations: {
setAuthStatus(state, loggedIn) {
state.loggedIn = loggedIn;
}
}
});
export default store;
router.js
router.beforeEach((to, from, next) => {
if (to.matched.some(route => route.meta.requiresAuth)) {
store.state.authStatus.then(loggedIn => {
if (loggedIn) next();
else next({ name: "home" });
});
} else {
next();
}
});
检查此解决方案是否有效 here
问题可能是因为当您输入 url https://example.com/account
它启动应用程序,axios 向服务器执行异步请求。 所以也许你应该尝试从 beforeEach 中进行 axios 调用。
通过这种方式,您可以毫无问题地验证用户。
问题是你不能使 axios 同步,所以你必须 return 与 axios 的承诺才能实现功能。
请告诉我这是否对您有帮助。
兜兜转转
store.js
:
const store = new Vuex.Store({
state: {
authStatus: axios.get(...).then(response => {
store.commit('setAuthStatus', true)
}),
userAuth: false
},
mutations: {
setAuthStatus(state, authStatus) {
state.userAuth = authStatus
}
}
})
router.js
:
router.beforeEach((to, from, next) => {
if (to.matched.some(route => route.meta.requiresAuth)) {
store.state.authStatus.then(() => {
//we're getting 200 status code response here, so user is authorized
//be sure that API you're consuming return correct status code when user is authorized
next()
}).catch(() => {
//we're getting anything but not 200 status code response here, so user is not authorized
next({name: 'home'})
})
} else {
next()
}
})