[Vue动态路由] vue实现动态路由 (专为后端同学而生)

引言:
不同的账号有不同的权限, 根据不同权限显示不同

粗略的流程图

首先 在router.js中定义基本路由(登录 404等)

const routes = [
    {
        path: '/',
        name: 'home',
        component: HomeView
    },
    {
        path: '/about',
        name: 'about',
        component: () => import('@/views/AboutView'),
    }
]

在当前文件定义前置处理

router.beforeEach((to, from, next) => {

    /**
     * 大体流程
     * 1. 定义路由白名单(登录等...), 放行
     * 2. token: 是否登录 未登录 跳转到login
     * 3. 根据token向后台获取菜单 权限等 (一般会本地存储 vuex结合localStore使用)
     * 4. 根据菜单构建动态路由
     * 5. next
     */
    // 仅为了演示
    console.log(to)
    // 向后台获取菜单树
    let menuList = getMenu('1');
    // 如果动态路由为空 (刷新也会清空 所以我们把动态路由放到vuex中 vuex刷新后也会清空)
    const length = store.state.routerList.length;
    if (length === 0) {
        loadDynamicRouter(menuList)
        next({...to, replace: true})
    }
    next();
})

// 加载路由
function loadDynamicRouter(menuList = []) {
    const routers = getRouter(menuList);
    // 设置路由
    routers.forEach(r => router.addRoute(r))
    // 解决刷新后页面404
    router.addRoute({'path': '*', component: () => import('@/views/404')})
    store.state.routerList = routers;
}
// 向后台获取菜单树
function getMenu(roleId) {
    const item = localStorage.getItem("MENU");
    if (item !== null) {
        return JSON.parse(item)
    }
    axios.get("http://localhost:48083/screen-gateway/get-menu?roleId=" + roleId).then(res => {
        const menuList = res.data.data;
        localStorage.setItem("MENU", JSON.stringify(menuList))
        return menuList;
    })
}

动态路由工具类.js

export function getRouter(menuList = []) {
    const routers = []
    menuRecursion(menuList, routers)
    return routers;
}

// 递归设置路由信息
function menuRecursion(menus = [], routers = []) {
    menus.forEach(menu => {
        if (menu.pid !== null && menu.pid !== 0) {
            const children = menu.children;
            children.forEach(child => {
                const route = getRealRoute(child);
                routers.push(route)
                // 递归实现
                menuRecursion(child.children, routers)
            })
        }
    })
}

/**
 * 获取路由标准
 */
function getRealRoute(item) {
    // 路由基本格式
    return {
        // 路由的路径
        path: item.component,
        // 路由名
        name: item.name,
        // 路由所在组件
        component: resolve => require([`@/views${item.component}.vue`], resolve),
        meta: {
            id: item.id,
            icon: item.icon
        },
        // 路由的子路由
        children: []
    }
}

引入element ui 根据每个人不同的权限 显示不同的菜单

<el-menu
          default-active="1"
          class="el-menu-vertical-demo"
          :router="true">

        <template v-for="menu  in menus">
          <el-submenu index=i v-if="menu.children !=null && menu.children.length>0">
            <!-- 有子菜单-->
            <template slot="title">
              <i class="el-icon-location"></i>
              <span>{{ menu.name }}</span>
            </template>

            <!-- 子菜单 -->
            <template v-for="child in menu.children">
              <el-menu-item :index="child.component" :path="child.component">
                <template>{{ child.name }}</template>
              </el-menu-item>
            </template>
          </el-submenu>

          <el-menu-item v-else>
            <i class="el-icon-location"></i>
            <span>{{ menu.name }}</span>
          </el-menu-item>
        </template>

      </el-menu>

后端代码

list转树的代码 https://blog.csdn.net/weixin_44912855/article/details/122175225
@GetMapping("/get-menu")
        public R<List<Perm>> getMenu(@RequestParam(defaultValue = "1") String roleId) {
        List<RolePerm> list = rolePermService.list(Wrappers.<RolePerm>lambdaQuery().eq(RolePerm::getRoleId, roleId));
        List<Perm> perms = permService.listByIds(list.stream().map(RolePerm::getPermId).collect(Collectors.toList()));
        // 转树
        ListToTreeHandler<Perm, String> handler = new ListToTreeHandler<>(perms, Perm::getId, Perm::getPid, Perm::setChildren);
        return R.success(handler.build());
    }

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值