我有一个带有 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()
});
为什么我的导航守卫在使用 router.push() 时会跳过? 这个问题是在使用 localeredirect 添加 i18n 之后开始的。所以所有路由都在一个语言环境之后,例如:/en/.../
答案 0 :(得分:1)
正如 Estus 在评论中指出的那样,问题是您要检查的第一件事是语言环境是否匹配,如果匹配,您将调用 next()
并将用户发送到页面。
如here所述:
<块引用>确保在通过导航守卫的任何给定传递中,下一个函数只被调用一次。它可以出现多次,但前提是逻辑路径没有重叠,否则钩子永远不会被解析或产生错误。
如果您需要在 to 和 from 页面之间保持区域设置检查,您可以执行以下操作:
if (to.params.locale === from.params.locale && loggedIn) {
next()
return
}
这将在将用户推送到他们试图导航到的页面之前检查 loginedIn 变量是否为真。
我相信只需删除检查语言环境是否匹配的 if 语句也可以。