解决router.beforeEach()动态加载路由出现死循环问题

当使用 Vue Router 动态加载路由时,可能会遇到一个循环加载的问题,具体表现为 beforeach 全部被拦截,因此会出现死循环。这个问题的根本原因是路由对象在创建并注册路由前会被复制,因此在路由注册前执行一个 beforeEach 全局钩子,将会陷入死循环。为了解决这个问题,我们可以采用以下方案:

步骤

步骤一

在路由配置文件中为动态路由添加一个命名字段,使其有一个唯一标识符,如下所示:

const routes = [
  {
    path: '/home',
    name: 'home',
    component: () => import('@/views/home/index.vue'),
  },
  {
    path: '/login',
    name: 'login',
    component: () => import('@/views/login/index.vue'),
  },
  {
    path: '/about-us',
    name: 'about-us',
    component: () => import('@/views/about-us/index.vue'),
  },
  {
    path: '/article-detail/:id',
    name: 'article-detail',
    component: () => import('@/views/article-detail/index.vue'),
    meta: {
      title: 'Article Detail',
      author: 'admin',
    },
  },
  {
    path: '/user/:id',
    name: 'user',
    component: () => import('@/views/user/index.vue'),
    meta: {
      title: 'User',
      author: 'admin',
    },
  },
  {
    path: '/404',
    name: '404',
    component: () => import('@/views/404.vue'),
    hidden: true,
  },
  {
    path: '*',
    redirect: '/404',
    hidden: true,
  },
  {
    path: '/admin',
    component: () => import('@/views/admin/index.vue'),
    meta: {
      title: 'Admin Dashboard',
      author: 'admin',
    },
    children: [
      {
        path: 'home',
        name: 'admin-home',
        component: () => import('@/views/admin/home.vue'),
        meta: {
          title: 'Admin Home',
          author: 'admin',
          roles: ['admin'],
        },
      },
      {
        path: 'users',
        name: 'admin-users',
        component: () => import('@/views/admin/users.vue'),
        meta: {
          title: 'Admin Users',
          author: 'admin',
          roles: ['admin'],
        },
      },
      {
        path: 'articles',
        name: 'admin-articles',
        component: () => import('@/views/admin/articles.vue'),
        meta: {
          title: 'Admin Articles',
          author: 'admin',
          roles: ['admin'],
        },
      }
    ]
  },
];

export default routes;

步骤二

在 router.beforeEach() 全局拦截器中,给每条动态路由添加一个标识符,然后再进行跳转,如下所示:

router.beforeEach((to, from, next) => {
  const whiteList = ['/login', '/404']; // 不重定向白名单
  if (whiteList.indexOf(to.path) !== -1) {
    next();
  } else {
    if (!store.getters.token) { // 没有token
      next('/login');
    } else {
      if (store.getters.roles.length === 0) { // 没有角色,需要动态加载角色
        store.dispatch('getUserRoles').then(res => { // 获取用户信息
          const roles = res.data.roles;
          store.commit('SET_ROLES', roles); // 存储用户角色
          const guestRoutes = router.options.routes; // 所有路由
          const routes = buildRoutesByRoles(guestRoutes, roles); // 根据角色筛选路由
          router.options.routes = routes; // 添加动态路由
          router.addRoutes(routes); // 动态添加路由
          next({ ...to, replace: true });
        }).catch(err => {
          store.dispatch('logout').then(() => {
            Message.error(err || 'Verification failed, please login again');
            next('/login');
          });
        });
      } else {
        if (hasPermission(store.getters.roles, to)) { // 校验权限
          next();
        } else {
          next('/404');
        }
      }
    }
  }
});

在这个例子中,我们首先获取到了所有路由,然后根据用户角色筛选出需要添加的那些路由,将这些路由添加到 Vue Router 中,最后再进行路由跳转,这样就能够避免路由被重复添加,从而解决了 beforeach 中的死循环问题。

示例

为了更好地说明这个解决方案的作用,我将提供两个例子,分别展示该方案在对不同场景下的解决作用。

示例一:多角色权限控制

当我们生成一套后台管理系统时,可能会遇到需要对用户进行角色管理,并且需要在页面中针对不同的角色展示出不同的内容。这就需要我们在路由配置文件中进行角色控制,根据当前用户的角色来动态加载对应角色的路由。这时候,我们就会存在 beforeach 中的死循环问题,需要使用以上解决方案进行处理。

示例二:菜单栏展开总是重复展示子菜单

有时候,我们用 Vue Router 实现菜单栏的功能时,可能会出现子菜单在切换时总是重复展开的问题。这是因为每次切换路由时,路由对象都会被复制一遍,从而导致路由钩子函数被多次调用,而 vue-router 会在每次调用路由钩子函数时重新实例化路由对象,从而导致菜单重复展示。这时候,我们可以使用以上方案解决死循环问题,从而解决菜单栏展开问题。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:解决router.beforeEach()动态加载路由出现死循环问题 - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • 详解Vue3 中的计算属性及侦听器

    详解Vue3 中的计算属性及侦听器 计算属性 计算属性是Vue中一种非常常见的属性类型,可以根据其他数据的变化而自动更新。在Vue3中,计算属性的写法有所变化,需要使用computed方法来定义。 <template> <div> <p>商品价格: {{ price }}</p> <p>打折后价格:…

    Vue 2023年5月28日
    00
  • 关于Vue的 Vuex的4个辅助函数

    下面是对于“关于Vue的 Vuex的4个辅助函数”的详细攻略: 什么是 Vuex 辅助函数? 在进行 Vuex 的开发过程中,我们需要在组件中访问 Vuex 的 state,mutations 和 actions 等内容,常规的做法是在组件中使用 this.$store.state.myState 这种方式来访问。但是这样的方式不仅冗长而且繁琐,我们需要频繁…

    Vue 2023年5月28日
    00
  • 关于axios不能使用Vue.use()浅析

    关于axios不能使用Vue.use()浅析 在vue项目中,我们通常使用axios来进行网络请求。然而,有些人会发现在使用Vue.use()加载axios插件时会报错,而直接在组件中使用axios却没有问题。这是因为axios并不是一个Vue插件,不能通过Vue.use()方法进行加载。下面将详细讲解这个问题以及如何解决。 问题分析 在一个Vue项目中,我…

    Vue 2023年5月28日
    00
  • 你可能不知道的typescript实用小技巧

    作为 Typescript 常见的使用者,也许你已经对它的一些语法特性熟悉,但是,你可能不知道的 Typescript 实用小技巧可不止这些。接下来我将为你讲解一些不太为人所知的 Typescript 实用小技巧,希望能够对你的开发带来帮助。 1. 类型断言(Type Assertion) 类型断言是一种告诉编译器更确切的类型信息的方式,它可以强制类型检查器…

    Vue 2023年5月28日
    00
  • vant时间控件使用方法详解

    Vant 时间控件使用方法详解 概述 Vant 是一款基于 Vue.js 的移动端组件库,其中包括了时间选择器(Picker)和日期选择器(DatetimePicker)等常用的时间控件。本文将详细介绍如何安装和使用 Vant 时间控件。 安装 通过 npm 安装 Vant: npm install vant -S 在 main.js 中引入 Vant: i…

    Vue 2023年5月29日
    00
  • Vue项目中实现带参跳转功能

    下面是Vue项目中实现带参跳转功能的完整攻略: 1. 传递参数 1.1 路由方式 我们可以利用 Vue Router 实现带参跳转,先看一下路由文件定义如下: import Vue from ‘vue’ import Router from ‘vue-router’ import Home from ‘@/views/home/Home’ import De…

    Vue 2023年5月27日
    00
  • Vue中的nextTick方法详解

    下面是Vue中的nextTick方法详解的完整攻略。 什么是nextTick方法 nextTick方法是Vue提供的一个异步操作工具,它可以让我们在DOM更新之后执行一些操作。它的作用是在下次DOM更新循环结束之后执行延迟回调,用于获得更新后的DOM。因此,使用nextTick方法可以让我们更加方便地操作更新后的DOM。 nextTick方法的基本应用 在V…

    Vue 2023年5月28日
    00
  • webpack搭建vue 项目的步骤

    下面我将介绍使用webpack搭建vue项目的步骤以及相关示例说明。 步骤一:初始化项目 首先,在本地创建一个空的文件夹,打开终端,进入该文件夹目录,执行以下命令: npm init -y 这个命令将会初始化一个Node.js 项目(-y 表示跳过初始化界面)。 步骤二:安装依赖 在项目根目录下执行以下命令安装webpack和vue相关依赖: npm i w…

    Vue 2023年5月28日
    00
合作推广
合作推广
分享本页
返回顶部