前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue-Router根据用户权限添加动态路由(侧边栏菜单)

Vue-Router根据用户权限添加动态路由(侧边栏菜单)

作者头像
岳泽以
发布2022-11-14 17:41:09
4.5K0
发布2022-11-14 17:41:09
举报
文章被收录于专栏:岳泽以博客岳泽以博客

动态路由

如果你的网页有管理员、普通用户等多种角色类型,不同的角色能看到的页面/菜单应该是不同的,所以不同的用户登录之后应该监听到不同的动态路由和渲染不同的菜单,这个时候就需要用到动态路由。

简单来说就是根据用户信息获取其对应的权限,生成对应的路由挂载,然后动态渲染有权限的菜单于侧边栏菜单。

实现思路图示:

使用到的路由方法:https://router.vuejs.org/zh/api/index.html#addroute

实现步骤

1、定义静态路由(包括登录、公用页面)、动态路由,且初始化时只挂载静态路由。

代码语言:javascript
复制
import { createRouter, createWebHashHistory } from 'vue-router'; //1.按需导入需要的方法
import Main from '../views/Main.vue';
const router = createRouter({
  //3.创建路由对象
  history: createWebHashHistory(), //3.1指定通过hash管理路由的切换
  routes: [
    //3.2创建路由规则
      //静态路由
    {
      path: '/',
      component: Main,
      name: 'Home',
      redirect: '/home',
      children: [
          //这里放公共的组件
        {
          path: '/user/usercenter',
          name: 'usercenter',
          component: () => import('../views/User/UserCenter.vue'),
        },
      ],
    },
    {
      path: '/login',
      name: 'login',
      component: () => import('../views/Login.vue'),
    },
  ],
});

export default router; //4.向外共享路由对象

2、用户登录成功,根据权限拿到数据并做持久化保存。

代码语言:javascript
复制
//登录的处理方法-main.js
const login = async () => {
      const res = await proxy.$api.getMenu(loginForm);
      // console.log(res);
      // 将获取到的菜单值传给store
      store.commit('setMenu', res.menu);
      // 动态添加路由菜单
      store.commit('addMenu', router);
    //获取的Token值存储
      store.commit('setToken', res.token);
      router.push({
        name: 'home',
      });
      ElMessage({
        message: '登录成功',
        type: 'success',
      });
    };

3、将数据处理之后使用addRoute方法添加到子路由。

因为这里的menuArray是作为home的二级路由添加的,所以在方法中指定home就能将menuArray添加为home的子路由。

代码语言:javascript
复制
    // 登录后获取到的菜单持久化保存
    setMenu(state, val) {
      state.menu = val;
      localStorage.setItem('menu', JSON.stringify(val));
    },
    // 添加路由菜单
    addMenu(state, router) {
      // 有无存储的菜单值判断
      if (!localStorage.getItem('menu')) {
        return;
      }
      // 如果有,将菜单值保存
      const menu = JSON.parse(localStorage.getItem('menu'));
      state.menu = menu;
      const menuArray = [];
      //3.处理数据
      menu.forEach((item) => {
        //如果存在子路由则将子路由保存
        if (item.children) {
          item.children = item.children.map((item) => {
            let url = `../views/${item.url}.vue`;
            item.component = modules[url];
            return item;
          });
            //添加到menuArray数组的children中
          menuArray.push(...item.children);
        } else {
          let url = `../views/${item.url}.vue`;
          item.component = modules[url];
            //添加到menuArray数组中
          menuArray.push(item);
        }
      });
        //添加生成的新菜单数组到路由
      menuArray.forEach((item) => {
        // 使用router.addRoute动态添加为Home的子路由
        router.addRoute('Home', item);
      });
    },

踩炕注意

刷新动态路由消失

页面刷新后,会造成动态路由消失,原因是因为在addRoute方法中:

提示 请注意,添加路由并不会触发新的导航。也就是说,除非触发新的导航,否则不会显示所添加的路由。

解决方案

在渲染之前直接添加

代码语言:javascript
复制
store.commit('addMenu', router);

app.use(router).use(store);
app.mount('#app');

路由懒加载

先简单介绍一些路由懒加载:

传统的写法:

代码语言:javascript
复制
//先导入组件
import Main from '../views/Main.vue';

//然后定义路由规则
routes: [
    { path: '/main',
      component: Main,
    },  
]

懒加载写法:

代码语言:javascript
复制
//直接写路由规则
routes: [
    { path: '/main',
      component: () => import('../views/Main.vue'),
    },  
]

懒加载就是按需去加载路由对应的资源,提高首屏加载速度,代码实现也很简单,但大大的提升了响应速度。

但是我在vite3中使用时,动态加载模板字符串的组件时报错,可以使用vite提供的Glob 导入。

它匹配到的文件默认也是懒加载的,具体解决方案看这篇文章:

Vue3和vite项目踩炕提示The above dynamic import cannot be analyzed by Vite.

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022 年 11 月,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 动态路由
  • 实现步骤
  • 踩炕注意
    • 刷新动态路由消失
      • 解决方案
    • 路由懒加载
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档