当前位置: 首页 > news >正文

React-router和Vue-router底层实现原理

React-router和Vue-router中有两种路由管理的方式,一种通过 ​​HTML5 History API​​ 实现,另外一种通过Hash实现。

一、通过 ​​HTML5 History API​​ 实现

通过 ​​HTML5 History API​​ 实现前端路由管理,是一种无需页面刷新即可切换视图(即单页应用,SPA)的常用方式。它主要利用了 history.pushState()、history.replaceState()和 popstate事件来实现无刷新 URL 变更和路由控制。

下面将详细介绍如何使用 HTML5 History API 实现一个简单的路由管理系统。

1、HTML5 History API 简介

HTML5 History API 提供了以下三个核心方法/事件:

​​history.pushState(state, title[, url])​​

  • 向浏览器历史记录栈中添加一条新记录。
  • ​​不会触发页面刷新或跳转​​。
  • url是可选的,可以是相对路径或绝对路径(但必须同源)。

​​history.replaceState(state, title[, url])​​

  • 替换当前历史记录,而不是新增。
  • 用途:比如更新当前页面的状态但不新增历史记录。

​​window.onpopstate事件​​

  • 当用户点击浏览器的前进/后退按钮时触发。
  • 可以通过 event.state获取之前通过 pushState/replaceState 设置的状态。

⚠️ 注意:这些 API ​​只修改 URL 和历史记录,不会自动加载页面内容或处理路由逻辑​​,需要开发者手动监听并执行相应的视图渲染逻辑。

2、基本思路

要实现一个基于 History API 的路由系统,通常需要以下几个部分:

  1. ​​监听 popstate 事件​​:处理浏览器前进/后退。
  2. ​​定义路由表​​:存储路径与对应处理函数的映射。
  3. ​​实现路由跳转函数(如 navigate)​​:使用 pushState改变 URL 并渲染对应视图。
  4. ​​拦截 <a>标签等链接点击事件​​:阻止默认跳转行为,使用自定义路由逻辑。
  5. ​​初始化:根据当前 URL 渲染对应视图​

3、一个简单的实现示例

下面是一个基于原生 JavaScript 的简单路由管理器实现:

3.1. HTML 示例

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8" /><title>HTML5 History API 路由示例</title>
</head>
<body><nav><a href="/home">首页</a><a href="/about">关于</a><a href="/contact">联系</a></nav><div id="app">正在加载...</div><script src="router.js"></script>
</body>
</html>

3.2. JavaScript 路由管理器(router.js)

// router.js// 简单的路由表:路径 => 处理函数
const routes = {'/home': () => renderView('首页内容'),'/about': () => renderView('关于我们'),'/contact': () => renderView('联系方式'),
};// 默认路由(404)
const notFound = () => renderView('404 - 页面未找到');// 渲染视图的函数
function renderView(content) {const app = document.getElementById('app');app.innerHTML = `<h1>${content}</h1>`;
}// 路由匹配与执行
function handleRoute() {const path = window.location.pathname; // 如 /home, /aboutconst routeHandler = routes[path] || notFound;routeHandler();
}// 自定义导航函数:改变URL并渲染页面
function navigate(path) {history.pushState({}, '', path); // 不修改标题,只改URLhandleRoute(); // 执行对应的视图渲染
}// 监听浏览器前进/后退
window.addEventListener('popstate', handleRoute);// 拦截页面中的 <a> 标签点击,使用路由跳转而不是整页刷新
document.addEventListener('click', function (e) {if (e.target.tagName === 'A' && e.target.getAttribute('href').startsWith('/')) {e.preventDefault(); // 阻止默认跳转const path = e.target.getAttribute('href');navigate(path);}
});// 页面初次加载时,根据当前路径渲染
document.addEventListener('DOMContentLoaded', handleRoute);

4、关键点解析

​​4.1、navigate(path)函数​​

使用 history.pushState()修改 URL,但不会刷新页面。

然后调用 handleRoute()来根据新的 URL 渲染对应内容。

​​4.2、popstate事件​​

当用户点击浏览器的前进/后退按钮时,会触发此事件,此时需要重新根据 window.location.pathname渲染页面。

​​4.3、拦截 <a>标签​​

阻止默认的页面跳转行为,使用自定义的 navigate()方法进行路由切换,保持单页体验。

​​4.4、初始化渲染​​

在页面加载(DOMContentLoaded)时,根据当前 URL 执行一次路由匹配和视图渲染。

5、进阶优化方向(可选)

上述示例是一个非常基础的路由实现,实际项目中你可能还需要考虑以下功能:

功能

说明

​动态路由(如 /user/:id)​

支持参数化路径,通过正则或路径分割提取参数

​路由守卫​

比如在进入某个路由前检查登录状态

​嵌套路由​

支持多级路由和组件嵌套渲染

​懒加载视图/组件​

按需加载路由对应的模块,提高性能

​Hash 模式降级支持​

如果不支持 History API,可使用 Hash (#) 模式作为备选

6、总结

✅ ​​HTML5 History API 路由管理的核心是:​​

  • 使用 pushState()/ replaceState()改变 URL,不刷新页面;
  • 监听 popstate事件处理浏览器的前进/后退;
  • 手动根据 URL 匹配路由并渲染视图;
  • 拦截链接点击,避免整页刷新,保持 SPA 体验。

二、通过Hash实现

1、什么是 Hash 路由?

在 URL 中,#后面的部分称为 ​​hash(锚点)​​,例如:

https://example.com/#/home

https://example.com/是页面路径;

#/home是 hash 部分,​​不会触发页面刷新​​;

浏览器监听 hashchange事件,当 hash 改变时,可以执行相应的 JavaScript 逻辑来切换视图内容。

2、Hash 路由的原理

​​2.1 URL 中的 Hash 不会触发页面刷新​​

改变 hash(如通过 location.hash = '#/about')不会导致页面重新加载。

​​2.2 监听 hash 变化​​

使用 window.addEventListener('hashchange', callback)监听 hash 的变化,根据不同的 hash 值渲染不同的内容。

​​2.3 映射 Hash 到对应的组件或页面逻辑​​

维护一个路由表(对象或数组),将不同的 hash 路径映射到对应的处理函数或组件。

3、如何用原生 JavaScript 实现一个简单的 Hash 路由?

下面是一个最基础的 Hash 路由实现示例:

1. HTML

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8" /><title>Hash Router Demo</title>
</head>
<body><nav><a href="#/">首页</a><a href="#/about">关于</a><a href="#/contact">联系</a></nav><div id="app"><!-- 路由内容将在这里显示 --></div><script src="router.js"></script>
</body>
</html>

2. JavaScript(router.js)

// 简单的 Hash 路由实现// 路由配置:path => 对应要展示的内容
const routes = {'/': '<h1>首页</h1><p>欢迎来到首页!</p>','/about': '<h1>关于我们</h1><p>这是关于页面。</p>','/contact': '<h1>联系我们</h1><p>这是联系页面。</p>'
};// 获取显示内容的容器
const app = document.getElementById('app');// 渲染函数:根据当前 hash 显示对应内容
function render() {const hash = window.location.hash.slice(1) || '/'; // 去掉 #,默认为 '/'const content = routes[hash] || '<h1>404 页面未找到</h1>';app.innerHTML = content;
}// 监听 hash 变化
window.addEventListener('hashchange', render);// 页面初次加载时也执行一次
window.addEventListener('DOMContentLoaded', render);

http://www.dtcms.com/a/392848.html

相关文章:

  • 宝藏音乐下载站,免费好用
  • pygame AI snake 大乱斗
  • TCP FIN,TCP RST
  • 睡眠PSG统一数据集的设计思路
  • 告别Vibe Coding!敏捷AI驱动开发:用AI高效构建可维护的复杂项目
  • EA-LSS:边缘感知 Lift-splat-shot 框架用于三维鸟瞰视角目标检测
  • 和为 K 的子数组
  • 从流量红利到运营核心:“开源AI智能名片+链动2+1模式+S2B2C商城小程序”驱动电商行业价值重构
  • 【ICLR 2024】MogaNet:多阶门控聚合网络
  • 小语言模型(SLM):构建可扩展智能体AI的关键
  • ​​[硬件电路-293]:不同频率对应不同周期时间对应表
  • 自定义你的tqdm
  • Tiny10 os是啥?原来是精简的Windows10
  • ThingsBoard部署APP过程错误-flutterr Resolving dependencies
  • webpack入门基础
  • 机器视觉VUE3手势识别+手势检测控制相机缩放
  • AI大模型:(三)1.3 Dify文本生成快速搭建旅游助手
  • Linux文件下载卡在0%进度问题处理
  • 【车载开发系列】区分Flash,RAM与E2PROM的概念
  • 未来展望:小模型撬动大未来
  • TenstoRT加速YOLOv11——python端加速
  • 探索LiveTalking:开启实时数字人交互新时代
  • 【开题答辩全过程】以 Javaweb的火花流浪动物救助系统设计与实现为例,包含答辩的问题和答案
  • 链家二手房数据爬虫与预测项目 Python 线性回归 Scrapy+Django+Echarts 机器学习 大数据✅
  • Heptagon: 一项Scade工具的学术版原型
  • 师徒对决!阿森纳战曼城伤病情况 预计两队共11人缺席
  • 第37篇:AI伦理:偏见、公平性与负责任的人工智能
  • ubuntu18.04 编译VTK
  • ES6 新增特性
  • Pycharm中切换虚拟环境