如何在JavaScript中实现路由守卫

来源:AI视频音频作者:小雨头衔:草根站长
导读:本期聚焦于小伙伴创作的《如何在JavaScript中实现路由守卫》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何在JavaScript中实现路由守卫》有用,将其分享出去将是对创作者最好的鼓励。

路由守卫是前端单页应用中用于控制路由跳转逻辑的功能,常用于权限校验、登录状态判断、页面跳转前置处理等场景。在Vue、React等框架中通常有内置的路由守卫能力,但理解原生JavaScript实现路由守卫的思路,能帮助我们更清晰地掌握路由控制的底层逻辑。

如何在JavaScript中实现路由守卫

路由守卫的核心需求

一个基础的路由守卫需要实现以下几个核心能力:

  • 监听路由的变化,包括页面加载时的初始路由和后续的路由跳转
  • 支持注册多个守卫函数,每个守卫可以决定是否允许路由跳转
  • 跳转前执行所有守卫逻辑,若任一守卫拒绝跳转则终止流程
  • 支持路由跳转时传递参数,守卫可以获取跳转相关的信息

实现思路拆解

1. 监听路由变化

前端路由通常分为hash模式和history模式,这里以更常用的hash模式为例,通过监听hashchange事件和页面加载时的load事件来捕获路由变化。

2. 路由匹配与守卫注册

我们需要维护一个路由配置表,存储路由路径和对应的组件或者处理逻辑,同时提供一个注册守卫的方法,允许开发者添加自定义的守卫函数。

3. 守卫执行逻辑

当路由发生变化时,先依次执行所有注册的守卫函数,每个守卫可以返回true表示允许跳转,返回false表示拒绝跳转,也可以通过返回Promise支持异步守卫逻辑。

完整实现代码

以下是基于hash模式的路由守卫完整实现示例:

// 路由管理器类
class RouterGuard {
  constructor() {
    // 存储路由配置
    this.routes = {};
    // 存储守卫函数列表
    this.guards = [];
    // 当前路由路径
    this.currentRoute = null;
    // 初始化监听
    this.initListener();
  }

  // 初始化路由监听
  initListener() {
    // 页面加载时处理初始路由
    window.addEventListener('load', () => {
      this.handleRouteChange(window.location.hash.slice(1) || '/');
    });
    // hash变化时处理路由
    window.addEventListener('hashchange', (e) => {
      const newHash = window.location.hash.slice(1) || '/';
      this.handleRouteChange(newHash);
    });
  }

  // 注册路由
  registerRoute(path, callback) {
    this.routes[path] = callback;
  }

  // 添加路由守卫
  addGuard(guardFn) {
    this.guards.push(guardFn);
  }

  // 处理路由变化
  async handleRouteChange(targetPath) {
    // 构造路由上下文对象
    const context = {
      from: this.currentRoute,
      to: targetPath,
      hash: window.location.hash
    };

    // 依次执行所有守卫
    for (const guard of this.guards) {
      const result = await guard(context);
      // 若守卫返回false,终止跳转
      if (result === false) {
        console.log('路由跳转被守卫拦截');
        return;
      }
    }

    // 执行路由对应的回调
    const routeCallback = this.routes[targetPath];
    if (routeCallback) {
      routeCallback(context);
      this.currentRoute = targetPath;
    } else {
      console.log('未找到对应路由');
    }
  }

  // 主动跳转路由
  push(path) {
    window.location.hash = path;
  }
}

// 使用示例
const router = new RouterGuard();

// 注册路由
router.registerRoute('/', (context) => {
  console.log('进入首页', context);
  document.getElementById('app').innerHTML = '首页内容';
});

router.registerRoute('/user', (context) => {
  console.log('进入用户页', context);
  document.getElementById('app').innerHTML = '用户页内容';
});

router.registerRoute('/admin', (context) => {
  console.log('进入管理页', context);
  document.getElementById('app').innerHTML = '管理页内容';
});

// 添加登录状态校验守卫
router.addGuard(async (context) => {
  console.log('执行登录校验守卫');
  // 模拟获取登录状态,实际项目中从本地存储或接口获取
  const isLogin = localStorage.getItem('isLogin') === 'true';
  // 访问需要权限的页面时校验登录状态
  if (context.to === '/admin' && !isLogin) {
    alert('请先登录');
    router.push('/');
    return false;
  }
  return true;
});

// 添加跳转日志守卫
router.addGuard((context) => {
  console.log(`路由从 ${context.from || '无'} 跳转到 ${context.to}`);
  return true;
});

// 页面中模拟登录按钮
document.getElementById('loginBtn').addEventListener('click', () => {
  localStorage.setItem('isLogin', 'true');
  alert('登录成功');
});

document.getElementById('logoutBtn').addEventListener('click', () => {
  localStorage.setItem('isLogin', 'false');
  alert('退出成功');
});

代码说明

上述代码中,RouterGuard类封装了路由守卫的核心逻辑:

  • routes对象存储路由路径和对应的处理逻辑,registerRoute方法用于添加路由配置
  • guards数组存储所有注册的守卫函数,addGuard方法用于添加守卫
  • handleRouteChange方法是核心处理逻辑,会先执行所有守卫,全部通过后才执行路由对应的回调
  • 守卫函数支持异步,通过await执行,方便处理接口校验等异步场景

使用时只需要实例化RouterGuard,注册路由和守卫,就可以实现自定义的路由拦截逻辑。如果需要适配history模式,只需要把hashchange监听替换为popstate监听,同时跳转时使用history.pushState方法即可,核心守卫逻辑不需要改动。

JavaScript路由守卫前端路由路由拦截修改时间:2026-06-30 00:09:32

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。