闭包实现路由守卫的核心是将权限规则与用户信息封存在函数作用域内,使守卫函数无需重复传参、保持逻辑复用与隔离;通过工厂函数接收权限列表并返回可访问该列表的校验函数,形成闭包,支持静态校验与动态更新权限两种模式。

用闭包实现路由守卫的核心,是把权限规则和当前用户信息“封存”在函数作用域内,让每次调用守卫时无需重复传入,同时保持校验逻辑的复用性和隔离性。
封装权限校验逻辑(闭包主体)
定义一个工厂函数,接收用户角色或权限列表作为参数,返回具体的守卫函数。这个返回的函数能持续访问外层函数的参数,形成闭包:
function createRouteGuard(allowedRoles) {
return function(route) {
// route 是目标路由配置,比如 { path: '/admin', meta: { roles: ['admin'] } }
const requiredRoles = route.meta?.roles || [];
const hasPermission = requiredRoles.some(role => allowedRoles.includes(role));
return hasPermission;
};
}
这样,allowedRoles 被安全地保留在闭包中,不会被外部篡改,也不必每次校验都传一遍。
配合路由配置使用(真实场景示例)
假设用户登录后拿到角色 ['user', 'editor'],可创建专属守卫:
const userGuard = createRouteGuard(['user', 'editor']);
// 模拟路由表
const routes = [
{ path: '/home', component: Home },
{ path: '/admin', component: Admin, meta: { roles: ['admin'] } },
{ path: '/editor', component: Editor, meta: { roles: ['editor'] } }
];
// 导航前校验
function navigateTo(to) {
if (!userGuard(to)) {
console.warn('无权限访问:', to.path);
throw new Error('Access denied');
}
// 执行跳转...
}
调用 navigateTo({ path: '/editor', meta: { roles: ['editor'] } }) 会通过;访问 /admin 则拒绝。
支持动态更新权限(进阶闭包模式)
如果权限可能变更(如用户中途被提权),可把权限存为闭包内的可变引用,并提供更新方法:
function createMutableRouteGuard(initialRoles) {
let currentRoles = [...initialRoles]; // 拷贝一份,避免外部直接修改
return {
check(route) {
const requiredRoles = route.meta?.roles || [];
return requiredRoles.some(role => currentRoles.includes(role));
},
updateRoles(newRoles) {
currentRoles = Array.isArray(newRoles) ? [...newRoles] : [];
}
};
}
// 使用
const guard = createMutableRouteGuard(['user']);
guard.check({ meta: { roles: ['user'] } }); // true
guard.updateRoles(['user', 'admin']);
guard.check({ meta: { roles: ['admin'] } }); // true
结合现代前端框架(如 Vue Router / React Router)
实际项目中,通常在导航守卫钩子中调用该闭包函数:
-
Vue Router 4:在
router.beforeEach中使用userGuard(to)判断并next(false)或重定向到登录页 -
React Router v6.4+:在
createBrowserRouter的loader或自定义 hook 中调用守卫,抛错触发ErrorBoundary
关键是把闭包生成的守卫函数作为纯逻辑单元注入,不耦合框架生命周期,提升可测试性。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











