Vue 路由器 - 使用 router.push() 时跳过导航守卫
Vue router - navigation guard is skipped when using router.push()
我有一个带有 i18n 的 Vue SPA 和一些需要通过导航守卫进行身份验证的视图。
当我未通过身份验证并通过浏览器转到 url 时:
examplepage.com/en/lockedpage
我被重定向到:
examplepage.com/en/login
很好,但是当我单击运行的按钮时:
@click="$router.push(`/${$i18n.locale}/lockedpage`)"
即使我没有通过身份验证,我也会进入该页面。
如果未通过身份验证,我想重定向到登录页面
这是我的 router.js:
import Vue from 'vue';
import Router from 'vue-router';
import Home2 from './views/Home2.vue';
import Login from './views/Login.vue';
import Register from './views/Register.vue';
import ErrorLanding from './views/ErrorLanding.vue'
import Root from "./Root"
import i18n, { loadLocaleMessagesAsync } from "@/i18n"
import {
setDocumentLang
} from "@/util/i18n/document"
Vue.use(Router);
const { locale } = i18n
export const router = new Router({
mode: 'history',
base: '/',
routes: [
{
path: '/',
redirect: locale
},
{
path: "/:locale",
component: Root,
children: [
{
name: 'Home',
path: '',
component: Home2,
},
{
name: 'Home2',
path: '/',
component: Home2,
},
{
name: 'Login',
path: 'login',
component: Login,
},
{
path: 'register',
component: Register,
},
{
path: 'lockedpage',
name: 'lockedpage',
webpackChunkName: "lockedpage",
meta: {authRequired: true},
component: () => import('./views/LockedPage.vue')
},
{
path: '*',
component: ErrorLanding,
name: 'NotFound'
}
]
}
],
router.beforeEach((to, from, next) => {
if (to.params.locale === from.params.locale) {
next()
return
}
const { locale } = to.params
loadLocaleMessagesAsync(locale).then(() => {
setDocumentLang(locale)
const publicPages = [ `/`, `/${locale}`, `/${locale}/`];
const authRequired = !publicPages.includes(to.path);
const loggedIn = localStorage.getItem('user');
const redirect = to.path;
if (authRequired && loggedIn === null) {
if(to.meta.authRequired === false) {
next();
}
else
next({ name: 'Login', query: { redirect: redirect } });
} else {
next();
}
})
next()
});
为什么我的 navigationguard 在使用 router.push() 时会跳过?
这个问题是在使用 localeredirect 添加 i18n 之后开始的。所以所有路线都在区域设置之后,例如:/en/.../
正如 Estus 在评论中指出的那样,问题是您要检查的第一件事是区域设置是否匹配,如果匹配,您将调用 next()
并将用户发送到页。
如概述here:
Make sure that the next function is called exactly once in any given pass through the navigation guard. It can appear more than once, but only if the logical paths have no overlap, otherwise the hook will never be resolved or produce errors.
如果您需要在收件人页面和发件人页面之间进行区域设置检查,您可以这样做:
if (to.params.locale === from.params.locale && loggedIn) {
next()
return
}
这将在将用户推送到他们试图导航到的页面之前检查 loggedIn 变量是否为真。
我相信只要删除检查语言环境是否匹配的 if 语句也可以。
我有一个带有 i18n 的 Vue SPA 和一些需要通过导航守卫进行身份验证的视图。
当我未通过身份验证并通过浏览器转到 url 时:
examplepage.com/en/lockedpage
我被重定向到:
examplepage.com/en/login
很好,但是当我单击运行的按钮时:
@click="$router.push(`/${$i18n.locale}/lockedpage`)"
即使我没有通过身份验证,我也会进入该页面。 如果未通过身份验证,我想重定向到登录页面
这是我的 router.js:
import Vue from 'vue';
import Router from 'vue-router';
import Home2 from './views/Home2.vue';
import Login from './views/Login.vue';
import Register from './views/Register.vue';
import ErrorLanding from './views/ErrorLanding.vue'
import Root from "./Root"
import i18n, { loadLocaleMessagesAsync } from "@/i18n"
import {
setDocumentLang
} from "@/util/i18n/document"
Vue.use(Router);
const { locale } = i18n
export const router = new Router({
mode: 'history',
base: '/',
routes: [
{
path: '/',
redirect: locale
},
{
path: "/:locale",
component: Root,
children: [
{
name: 'Home',
path: '',
component: Home2,
},
{
name: 'Home2',
path: '/',
component: Home2,
},
{
name: 'Login',
path: 'login',
component: Login,
},
{
path: 'register',
component: Register,
},
{
path: 'lockedpage',
name: 'lockedpage',
webpackChunkName: "lockedpage",
meta: {authRequired: true},
component: () => import('./views/LockedPage.vue')
},
{
path: '*',
component: ErrorLanding,
name: 'NotFound'
}
]
}
],
router.beforeEach((to, from, next) => {
if (to.params.locale === from.params.locale) {
next()
return
}
const { locale } = to.params
loadLocaleMessagesAsync(locale).then(() => {
setDocumentLang(locale)
const publicPages = [ `/`, `/${locale}`, `/${locale}/`];
const authRequired = !publicPages.includes(to.path);
const loggedIn = localStorage.getItem('user');
const redirect = to.path;
if (authRequired && loggedIn === null) {
if(to.meta.authRequired === false) {
next();
}
else
next({ name: 'Login', query: { redirect: redirect } });
} else {
next();
}
})
next()
});
为什么我的 navigationguard 在使用 router.push() 时会跳过? 这个问题是在使用 localeredirect 添加 i18n 之后开始的。所以所有路线都在区域设置之后,例如:/en/.../
正如 Estus 在评论中指出的那样,问题是您要检查的第一件事是区域设置是否匹配,如果匹配,您将调用 next()
并将用户发送到页。
如概述here:
Make sure that the next function is called exactly once in any given pass through the navigation guard. It can appear more than once, but only if the logical paths have no overlap, otherwise the hook will never be resolved or produce errors.
如果您需要在收件人页面和发件人页面之间进行区域设置检查,您可以这样做:
if (to.params.locale === from.params.locale && loggedIn) {
next()
return
}
这将在将用户推送到他们试图导航到的页面之前检查 loggedIn 变量是否为真。
我相信只要删除检查语言环境是否匹配的 if 语句也可以。