Vue 路由器 - 使用 router.push() 时跳过导航守卫

时间:2021-07-28 13:54:41

标签: vue.js navigation vue-router browser-history vue-i18n

我有一个带有 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/.../

1 个答案:

答案 0 :(得分:1)

正如 Estus 在评论中指出的那样,问题是您要检查的第一件事是语言环境是否匹配,如果匹配,您将调用 next() 并将用户发送到页面。

here所述:

<块引用>

确保在通过导航守卫的任何给定传递中,下一个函数只被调用一次。它可以出现多次,但前提是逻辑路径没有重叠,否则钩子永远不会被解析或产生错误。

如果您需要在 to 和 from 页面之间保持区域设置检查,您可以执行以下操作:

if (to.params.locale === from.params.locale && loggedIn) {
     next()
     return
   }

这将在将用户推送到他们试图导航到的页面之前检查 loginedIn 变量是否为真。

我相信只需删除检查语言环境是否匹配的 if 语句也可以。