Vue3实现动态路由与手动导航

 更新时间:2024年12月13日 09:39:31   作者:头发秃头小宝贝  
这篇文章主要为大家详细介绍了如何在 Vue 3 中实现动态路由注册和手动导航,确保用户访问的页面与权限对应,感兴趣的小伙伴可以跟随小编一起学习一下

在后台管理系统中,前端的路由往往需要根据用户的权限动态生成。这篇文章将重点介绍如何在 Vue 3 中实现动态路由注册手动导航,确保用户访问的页面与权限对应。

1. 动态路由的需求与原理

为什么需要动态路由?

  • 权限控制:不同用户角色需要看到不同的菜单和页面。
  • 后端驱动:后端返回菜单数据,前端动态渲染菜单和注册路由。
  • 避免硬编码:路由不再写死在前端代码里,保证灵活性。

动态路由的原理

  • 静态路由:定义公共页面,如登录页和404页面。
  • 动态路由:存储需要通过后端数据动态添加的页面。
  • 动态注册路由:根据后端返回的数据,通过 router.addRoute 动态添加到路由系统。
  • 手动导航:添加新路由后,需要手动触发导航以保证路由生效。

2. 静态路由与动态路由配置

静态路由

静态路由是所有用户共享的基本路由,如登录页、404页等。

import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
import Layout from '@/layout/admin.vue';

const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    component: Layout,
    name: 'admin',
  },
  {
    path: '/login',
    name: 'login',
    component: () => import('@/pages/login/index.vue'),
    meta: { title: '登录页' },
  },
  {
    path: '/:pathMatch(.*)*',
    name: 'NotFound',
    component: () => import('@/pages/404/index.vue'),
    meta: { title: '404' },
  },
];

动态路由

动态路由需要根据后端返回的数据进行注册:

const asyncRoutes: Array<RouteRecordRaw> = [
  {
    path: '/',
    name: '/',
    component: () => import('@/pages/index/index.vue'),
    meta: { title: '首页' },
  },
  {
    path: '/goods/list',
    name: '/goods/list',
    component: () => import('@/pages/goods/list.vue'),
    meta: { title: '商品列表' },
  },
  {
    path: '/category/list',
    name: '/category/list',
    component: () => import('@/pages/category/list.vue'),
    meta: { title: '分类列表' },
  },
];

3. addRoutes 实现动态路由注册

addRoutes 方法

该方法接收后端返回的菜单数组,并将匹配的动态路由添加到主路由 admin 下。

import { router } from '@/router/index';

export const addRoutes = (routesArray: Array<MenusArray>) => {
  let hasNewRoutes = false;

  const addRoutesFromMenus = (menus: Array<MenusArray>) => {
    menus.forEach((menu) => {
      // 查找匹配的动态路由
      const route = asyncRoutes.find((r) => r.path === menu.frontpath);
      // 添加到router中
      if (route && !router.hasRoute(route.path)) {
        router.addRoute('admin', route);
        hasNewRoutes = true;
      }
      // 递归处理子菜单
      if (menu.child && menu.child.length > 0) {
        addRoutesFromMenus(menu.child);
      }
    });
  };

  addRoutesFromMenus(routesArray);
  return hasNewRoutes;
};

解释

  • router.addRoute:Vue Router 提供的 API,可以动态添加路由。
  • 避免重复添加router.hasRoute 检查路由是否已存在,防止重复注册。
  • 递归处理:支持多级菜单,递归遍历 child 子菜单。

4. 路由守卫中调用 addRoutes

router.beforeEach 路由守卫中,调用 addRoutes 注册动态路由,并实现手动导航

import { getToken } from '@/utils/auth';
import store from '@/store';
import { addRoutes } from '@/router/index';

router.beforeEach(async (to, from, next) => {
  const token = getToken();
  let hasNewRoutes = false;

  // 显示全局加载状态
  showFullLoading();

  // 未登录跳转到登录页
  if (!token && to.name !== 'login' && to.name !== 'NotFound') {
    return next('/login');
  }

  // 已登录访问登录页,重定向到主页
  if (token && to.name === 'login') {
    return next('/');
  }

  // 已登录状态下,动态添加路由
  if (token) {
    await store.dispatch('user/getUserInfo'); // 拉取用户信息
    hasNewRoutes = addRoutes(store.getters['menu/getMenus']); // 添加动态路由
  }

  // 设置页面标题
  if (to.meta.title) {
    document.title = `${to.meta.title}-测试后台管理`;
  } else {
    document.title = '测试后台管理';
  }

  // 手动导航:如果添加了新路由,重新跳转当前页面
  hasNewRoutes ? next(to.fullPath) : next();
});

手动导航的必要性

  • router.addRoute 是动态操作,添加新路由后需要重新跳转一次,确保用户能正常访问新注册的页面。
  • next(to.fullPath):手动跳转到当前页面。

5. 完整流程

  • 用户登录:获取用户 token,拉取用户信息。
  • 获取菜单数据:后端返回用户权限对应的菜单数据。
  • 动态注册路由:调用 addRoutes 将菜单数据匹配的路由添加到 admin 下。
  • 手动导航:动态路由添加完成后,使用 next(to.fullPath) 手动触发页面跳转。
  • 权限生效:用户只能访问与自己权限匹配的页面。

6. 总结

  • 静态路由:用于公共页面。
  • 动态路由:后端驱动,通过 addRoutes 动态注册。
  • 手动导航:解决动态添加路由后无法直接访问的问题。
  • 灵活性:动态路由使前端代码更灵活,后端控制权限更方便。

以上就是Vue3实现动态路由与手动导航的详细内容,更多关于Vue3动态路由与手动导航的资料请关注脚本之家其它相关文章!

相关文章

  • Vue3中reactive与ref函数使用场景

    Vue3中reactive与ref函数使用场景

    这篇文章主要为大家介绍了Vue3 中有场景是 reactive 能做而 ref 做不了的使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • 详解vuex状态管理模式

    详解vuex状态管理模式

    这篇文章主要介绍了详解vuex状态管理模式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11
  • vue页面params传值的坑及解决

    vue页面params传值的坑及解决

    这篇文章主要介绍了vue页面params传值的坑及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • vue组件常用的父子、兄弟、跨组件等传值方法

    vue组件常用的父子、兄弟、跨组件等传值方法

    Vue常用的三种传值方式有: •父传子 •子传父 •非父子传值 引用官网的一句话:父子组件的关系可以总结为 prop 向下传递,事件向上传递,熟悉vue各类关系的组件之间传值方法会令开发更加得心应手,下面将对父子、兄弟、页级组件之间的传值作浅谈
    2023-12-12
  • 详细聊聊Vue中的MVVM模式原理

    详细聊聊Vue中的MVVM模式原理

    MVVM旨在利用WPF中的数据绑定函数,通过从视图层中几乎删除所有GUI代码(代码隐藏),更好地促进视图层开发与模式其余部分的分离,这篇文章主要给大家介绍了关于Vue.js中MVVM的相关资料,需要的朋友可以参考下
    2023-03-03
  • 解决vue运行报错Error:Cannot find module '@vue/cli-plugin-babel'

    解决vue运行报错Error:Cannot find module '@vue/cli-plugin-b

    解决了因为版本问题在创建项目时出现的各种报错问题,这次在运行时出现的问题,下面这篇文章主要给大家介绍了关于解决vue运行报错Error:Cannot find module '@vue/cli-plugin-babel'的相关资料,需要的朋友可以参考下
    2023-04-04
  • Vue设置长时间未操作登录自动到期返回登录页

    Vue设置长时间未操作登录自动到期返回登录页

    这篇文章主要介绍了Vue设置长时间未操作登录以后自动到期返回登录页,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2020-01-01
  • 如何在vue3中使用滑块检验vue-puzzle-verification

    如何在vue3中使用滑块检验vue-puzzle-verification

    这篇文章主要介绍了在vue3中使用滑块检验vue-puzzle-verification的相关资料,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2023-11-11
  • 关于VUE点击父组件按钮跳转到子组件的问题及解决方案

    关于VUE点击父组件按钮跳转到子组件的问题及解决方案

    本文主要介绍了在Vue框架中,如何通过父组件的点击事件打开子组件中的弹窗并展示表格内容,主要步骤包括在父组件中定义数据属性,创建并定义子组件的弹窗和表格内容,通过props属性和自定义事件实现父子组件间的数据传递和方法调用
    2024-10-10
  • vue实现锚点跳转scrollIntoView()使用案例

    vue实现锚点跳转scrollIntoView()使用案例

    这篇文章主要介绍了vue实现锚点跳转scrollIntoView()使用案例,文中结合实例代码介绍了vue锚点跳转的三种方式(页内跳转,跨页跳转,函数跳转),需要的朋友可以参考下
    2023-07-07

最新评论