vue-router@4.x 路由权限控制

1、简介

在使用vue-router@next开发路由权限控制的时候,对于前后端分离的项目总有那么几分说不出的无奈。本篇文章主要介绍的是前后端分离的单页面前端路由权限控制。注意我无法保证此方法完美的控制,如果你想要完美的达到路由权限控制,请放弃此方法。

2、实现原理

之前写过一篇vue-router 控制路由权限的文章,使用的原理都是beforeEach全局钩子和addroute方法动态添加路由。如果不知道具体流程的朋友可以查看之前的实现思路图;本文只是之前的优化版本。

  • 1、在全局钩子beforeEach处理匹配路由,如果匹配放行。
  • 2、对于未匹配的做进一步登录判断,如果未登录跳转登录(注意带上返回地址)
  • 3、已经登录的再进一步判断是否从后台获取过菜单或者路由权限。如果已经获取过路由的就可以直接跳转至“没有权限”
  • 4、注意同步获取菜单或者路由权限,并处理调用路由实例addroute方法动态添加路由。
  • 5、添加完成后,由于当前处于未匹配路由状态。所以需要手动调用next()跳转路由。

3、优化方案

相比之前的方案,本次优化在于无需在代码中编辑对应动态路由。可通过import()动态实现路由配置,完成动态添加。

实现代码实例:

import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";

const routes: Array<RouteRecordRaw> = [
    {
        path: "/",
        component: () => import("@/views/home.vue"),
    },
    {
        path: "/about",
        component: () => import("@/views/about.vue"),
    },
    {
        path: "/login",
        component: () => import("@/views/login.vue"),
    },
    {
        path: "/404",
        component: () => import("@/views/404.vue"),
    },
    {
        path: "/permission-deni",
        component: () => import("@/views/permission-deni.vue"),
    },
];

const router = createRouter({
    history: createWebHistory("/g"),
    routes,
});

const isLogin = function () {
    let login = sessionStorage.getItem("auth");
    return !!login;
};

async function addRouters() {
    let authRouters = await getAuth();
    authRouters.forEach(({ path }) => {
        isMenu = true;
        // 动态添加
        router.addRoute({
            path,
            component: () => import(`./views${path}.vue`),
        });
    });

    console.log(">>>", router.getRoutes());
}

// 获取权限路由
function getAuth() {
    return new Promise<Array<{ path: string }>>((resolve) => {
        setTimeout(() => {
            let authRouters = [
                {
                    path: "/auth/edit",
                },
                {
                    path: "/auth/userinfo",
                },
            ];
            resolve(authRouters);
        }, 150);
    });
}

// 路由拦截
let isMenu = false; // 标记是否获取过菜单
router.beforeEach(async (to, from, next) => {
    let { matched } = to;
    let isMatched = !!matched.length;

    if (!isMatched) {
        // 为匹配到路由
        if (isLogin()) {
            // 已登录
            if (isMenu) {
                // 没有权限
                next("/permission-deni");
            } else {
                // 动态添加路由
                await addRouters();
                next(to.path);
            }
        } else {
            // 未登录
            next("/login");
        }
    } else {
        next();
    }
});

export default router;
复制代码

4、总结

再次强调,如果需要完美控制路由权限的请交给后台控制。本文只是对于之前的优化补充,完善通过后台系统配置完成路由设置。当然,还要处理的细节比较多;比如嵌套、别名、SEO等问题。具体需要请根据需求扩展。

完整示例代码可查看vue-auth

萌新,如有错误欢迎指正 (ง •_•)ง ;一起学习,一起进步

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享