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

yizhihongxing

当使用 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日

相关文章

  • Vue-cli中post请求发送Json格式数据方式

    Vue-cli 是一个官方提供的 Vue.js 项目脚手架,可以快速搭建 Vue.js 项目。 在 Vue-cli 中,如果要发送 POST 请求并且数据格式为 JSON,则需要使用 axios 库来发送请求。下面是详细的攻略。 步骤 安装 axios 库 在 Vue-cli 中,使用 npm 包管理器安装 axios 库非常方便,只需要在终端中执行以下命令…

    Vue 2023年5月28日
    00
  • vue上传图片文件的多种实现方法

    下面是关于“vue上传图片文件的多种实现方法”的完整攻略。 1. 前言 在现代Web应用程序中,上传文件是非常常见的需求之一。在Vue.js中,我们可以利用一些第三方库(如 axios 和 vue-resource)来实现上传文件的功能。本篇攻略将会探讨Vue.js中上传图片文件的多种实现方法。 2. 使用FormData对象实现上传 FormData是一种…

    Vue 2023年5月28日
    00
  • vue 获取元素额外生成的data-v-xxx操作

    当Vue渲染一个组件的时候,会自动生成一些指令,如data-v-xxx。这些指令是Vue为了保证组件的封装性、作用域隔离、样式隔离等方面做出的设计。如果应用CSS属性的时候直接写在后代元素上,并且如果后代元素被渲染成为一个组件,这个样式将不会应用到这个后代元素上,导致样式失效。 Vue提供了一些API来获取这些额外生成的data-v-xxx操作,常见的方式有…

    Vue 2023年5月29日
    00
  • springboot vue接口测试前端动态增删表单功能实现

    下面是关于“springboot vue接口测试前端动态增删表单功能实现”的完整攻略: 一、概述 这篇攻略介绍了如何使用Spring Boot和Vue.js构建一个带有动态增删表单功能的前端页面,并且可以通过接口测试实现数据的增删查改等操作。 二、环境搭建 为了正确地使用Spring Boot和Vue.js开发本示例,我们需要安装以下环境: Java Dev…

    Vue 2023年5月28日
    00
  • vue学习教程之带你一步步详细解析vue-cli

    Vue学习教程之带你一步步详细解析vue-cli 前言 Vue.js是一个轻量级的JavaScript框架,它与React和Angular一起组成了前端三大框架。Vue.js由开发者Evan You创建,它的双向数据绑定和组件化思想极大地提高了前端开发的效率。 随着Vue.js的发展,它的生态系统也日益完善。vue-cli是Vue.js的脚手架工具,它可以帮…

    Vue 2023年5月27日
    00
  • 在vue中使用jsx语法的使用方法

    在Vue中使用JSX语法需要满足以下条件: 安装vue-template-compiler包 配置Webpack,使得Webpack可以识别.jsx文件并转换成Vue组件 在组件中使用JSX语法 下面是详细的步骤: 1. 安装vue-template-compiler包 在使用JSX语法之前,需要安装vue-template-compiler包。 npm i…

    Vue 2023年5月28日
    00
  • 在Vue中实现添加全局store

    下面给您详细讲解在Vue中实现添加全局store的完整攻略: 步骤一:在Vue中创建store实例 在Vue中,我们可以使用Vuex来实现全局store功能,因此首先需要在Vue项目中安装并引用Vuex库: npm install vuex –save 在Vue项目中引用Vuex库: import Vuex from ‘vuex’ Vue.use(Vuex…

    Vue 2023年5月27日
    00
  • 详解Vue中watch的高级用法

    详解Vue中watch的高级用法 Vue中的watch是一个非常重要的属性,它用于监听数据的变化并执行相应的回调函数。除了最基本的用法,Vue中的watch还有一些高级用法,本文将针对这些高级用法进行详细讲解。 watch的基本用法 先来回顾一下watch的基本用法。在Vue实例中使用watch属性来监听某个数据的变化,代码如下所示: data() { re…

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