前端路由手写Hash和History两种模式

文章目录

        • 1. Hash模式:简洁而广泛适用
        • 2. History模式:更自然的用户体验
        • 3. 结论

在这里插入图片描述

在现代Web开发中,单页面应用(Single Page Application,简称SPA)因其流畅的用户体验和高效的页面交互能力而备受青睐。前端路由作为SPA的核心技术之一,允许用户在不刷新整个页面的情况下,通过URL的变化来加载和切换不同的页面内容。本文将通过手写代码的方式,深入探讨前端路由的两种主流实现方式:Hash模式和History模式。

1. Hash模式:简洁而广泛适用

Hash模式利用URL的哈希(#之后的部分)来存储路由信息,由于哈希的变化不会触发完整的页面刷新,因此非常适合于实现SPA的前端路由。下面是一个使用Hash模式的手写路由实现示例:

<!-- HTML结构 -->
<nav id="nav"><ul><li><a href="#/page1">Page 1</a></li><li><a href="#/page2">Page 2</a></li></ul>
</nav>
<div id="content"></div>
class HashRouter {constructor() {this.routes = {};window.addEventListener('hashchange', this.load.bind(this), false);this.load();}register(path, callback) {this.routes[path] = callback;}load() {let hash = window.location.hash.slice(1);let handler = this.routes[hash] || (() => {});handler.call(this);}
}let router = new HashRouter();
router.register('/page1', () => document.getElementById('content').innerHTML = 'Page 1 Content');
router.register('/page2', () => document.getElementById('content').innerHTML = 'Page 2 Content');

在这个示例中,我们监听hashchange事件,每当URL的哈希部分发生变化时,都会触发load方法,根据当前的哈希值加载相应的内容。Hash模式的一个主要优点是它的广泛兼容性,几乎所有的浏览器都支持哈希的变化。

这里有一个细节就是使用bind来“绑定”this

当你在事件监听器中直接使用this.load,在事件触发时,this的值会根据调用上下文来决定,通常在这种情况下,this会指向事件发生的元素(比如window对象,因为在hashchange事件中,this通常指的是window)。这可能会导致你的load方法无法访问到HashRouterHistoryRouter实例的属性和方法,因为this不再指向你期望的实例。

为了避免这个问题,使用bind方法来“绑定”this值,确保无论load方法在哪里被调用,其内部的this都会指向HashRouterHistoryRouter的实例。这样,load方法就能正确访问和操作实例上的属性和方法,如this.routesthis.load方法自身。

简而言之,使用this.load.bind(this)是为了确保load方法的this上下文正确无误,使其能够访问到所在类实例的成员,从而正确执行路由逻辑。如果不使用bindthis可能会指向错误的对象,导致方法无法按预期工作。
在这里插入图片描述

2. History模式:更自然的用户体验

History模式利用HTML5的History API(包括pushState, replaceStatepopstate事件)来管理浏览器的历史记录。相比于Hash模式,History模式能够提供更加自然的URL结构,没有显眼的#符号,使URL看起来更像是传统的多页面应用。说多了就是少个#让人觉得更好看一点

<!-- HTML结构 -->
<nav id="nav"><ul><li><a href="/page1">Page 1</a></li><li><a href="/page2">Page 2</a></li></ul>
</nav>
<div id="content"></div>
class HistoryRouter {constructor() {this.routes = {};window.addEventListener('popstate', this.load.bind(this), false);this.load();}register(path, callback) {this.routes[path] = callback;}load() {let path = window.location.pathname;let handler = this.routes[path] || (() => {});handler.call(this);}navigate(path) {history.pushState({}, '', path);this.load();}
}let router = new HistoryRouter();
router.register('/page1', () => document.getElementById('content').innerHTML = 'Page 1 Content');
router.register('/page2', () => document.getElementById('content').innerHTML = 'Page 2 Content');document.querySelectorAll('#nav a').forEach(link => {link.addEventListener('click', (e) => {e.preventDefault();router.navigate(e.target.href);});
});

在History模式下,我们通过监听popstate事件来捕获URL的变化,并通过pushState方法来改变当前的URL,同时保持页面不刷新。这里这种history方法可能会受到file://协议的限制,导致pushState代码运行不了。最推荐的方法是在本地搭建一个HTTP服务器来运行你的项目,而不是直接打开.html文件。这样可以绕过file://协议的限制。如果你使用的是vs code的呢,就右键文件通过open with live server方法打开,这个功能允许你快速启动一个轻量级的HTTP服务器,用于预览和测试你的HTML、CSS和JavaScript代码,而无需手动配置服务器环境。

在这里插入图片描述

3. 结论

无论是Hash模式还是History模式,每种方法都有其独特的优缺点。Hash模式易于实现且兼容性好,而History模式则提供更美观的URL和更自然的浏览体验。在实际项目中,根据应用的具体需求和目标用户群体,选择合适的前端路由模式至关重要。通过手写代码实践,我们不仅能加深对这两种模式的理解,还能更好地掌握如何在真实项目中灵活运用前端路由技术。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/46705.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PyTorch人脸识别

新书速览|PyTorch深度学习与企业级项目实战-CSDN博客 一套基本的人脸识别系统主要包含三部分&#xff1a;检测器、识别器和分类器&#xff0c;流程架构如图11-3所示&#xff1a; 图11-5 检测器负责检测图片中的人脸&#xff0c;再将检测出来的人脸感兴趣区域&#xff08;Reg…

第二届大数据、计算智能与应用国际会议(BDCIA2024)

会议日期&#xff1a;2024年11月15-17日 会议地点&#xff1a;中国-湖北省-黄冈市 主办单位&#xff1a;黄冈师范学院 【大会主席】 【主讲嘉宾】 大会邀请到来自美国、英国、加拿大、新加坡、意大利、越南等10余位领域内学术大咖作主题报告&#xff0c;并与参会人员互动交…

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【查询密钥是否存在(ArkTS)】

查询密钥是否存在(ArkTS) HUKS提供了接口供应用查询指定密钥是否存在。 开发步骤 指定密钥别名keyAlias&#xff0c;密钥别名最大长度为64字节。初始化密钥属性集。用于查询时指定密钥的属性TAG&#xff0c;比如查询的密钥范围(全量/单个)&#xff0c;当查询单个时&#xff…

分布式IO系统BL201 Profinet耦合器

BL201耦合器是一个数据采集和控制系统&#xff0c;基于强大的32 位微处理器设计&#xff0c;采用Linux操作系统&#xff0c;是一种模块化的分布式I/O系统。该系统由3部分组成&#xff1a;现场总线耦合器和各种类型的&#xff08;数字和模拟信号以及特殊功能&#xff09;I/O模块…

Ubuntu18 中JDK的安装

文章目录 一、背景说明二、获取安装包三、安装JDK3.1 上传安装包3.2 复制和解压3.3 环境变量的设置3.4 验证安装 四、问题列表4.1 .bashrc文件在哪里&#xff1f;.bashrc是什么&#xff1f;4.2 为什么使用rz上传安装包时会报&#xff1a; 传输失败&#xff1f; 五、总结 一、背…

解决RuntimeError: Couldn‘t load custom C++ ops. This can happen if your PyTorch

问题描述 刚下好yolov8的代码&#xff0c;想测一下能否成果&#xff0c;果然没成功&#xff0c;报错如下 RuntimeError: Couldnt load custom C ops. This can happen if your PyTorch and torchvision versions are incompatible, or if you had errors while compiling tor…

kettle从入门到精通 第七五课 ETL之kettle血缘,数据血缘

在了解kettle血缘之前&#xff0c;咱们先来了解下什么是数据血缘&#xff1f; 1、数据血缘定义&#xff08;来自gpt&#xff09; 数据血缘&#xff08;Data Lineage&#xff09;是指在数据管理和数据分析中追踪数据的源头、流向和处理过程的能力。具体来说&#xff0c;数据血…

《昇思25天学习打卡营第21天|基于 MindSpore 实现 BERT 对话情绪识别》

#学习打卡第21天# 1. BERT 模型 BERT全称是来自变换器的双向编码器表征量&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;&#xff0c;它是Google于2018年末开发并发布的一种新型语言模型&#xff0c;是基于Transformer中的Encoder并加上双向…

org/openxmlformats/schemas/spreadsheetml/x2006/main/CTWorkbook$Factory

org/openxmlformats/schemas/spreadsheetml/x2006/main/CTWorkbook$Factory POI的问题 在操作Excel时&#xff0c;出现这个问题是因为缺少了poi-ooxml-schema jar包&#xff0c;并且与poi的jar包版本一致

昇思25天学习打卡营第21天 | 基于MindSpore的红酒分类实验

内容简介 本实验介绍了使用MindSpore框架实现K近邻算法&#xff08;KNN&#xff09;对红酒数据集进行分类的全过程。通过数据读取、预处理、模型构建与预测&#xff0c;展示了KNN算法在红酒数据集上的应用。实验中详细解释了KNN的原理、距离度量方式及其在分类问题中的应用&…

PyTorch张量创建和随机数生成器算法

文章目录 1、基本创建方式1.1、根据已有数据创建张量1.2、根据已有数据创建张量1.3、根据已有数据创建张量 2、创建线性和随机张量2.1、创建线性空间的张量2.2、创建随机张量2.3、什么是随机数种子2.4、initial_seed()和manual_seed() 3、创建01张量3.1、全0张量3.2、全1张量3.…

【Java18】初始化块

初始化块和构造器、成员变量、成员方法一起&#xff0c;是唯四能在类中出现的成员。 初始化块的作用和构造器类似&#xff0c;目的是对对象进行初始化操作&#xff1b;一个类中可以有多个初始化块&#xff1b;初始化块只有两种修饰方式&#xff1a;static和default。用static修…

nginx生成自签名SSL证书配置HTTPS

一、安装nginx nginx必须有"--with-http_ssl_module"模块 查看nginx安装的模块&#xff1a; rootecs-7398:/usr/local/nginx# cd /usr/local/nginx/ rootecs-7398:/usr/local/nginx# ./sbin/nginx -V nginx version: nginx/1.20.2 built by gcc 9.4.0 (Ubuntu 9.4.0…

Android Studio - adb.exe已停止运作的解决方案

adb.exe 是Android Debug Bridge 的缩写&#xff0c;它是Android SDK 中的一个调试工具&#xff0c;允许开发者通过命令行界面与设备进行交互&#xff0c;执行各种操作&#xff0c;如运行设备的shell、管理模拟器或设备的端口映射、在计算机和设备之间上传/下载文件、将本地APK…

我的GeneFace++部署与运行之旅

文章目录 引言项目背景概述重要性分析结论 环境准备1. 安装CUDA2. 安装Python依赖3. 准备3DMM模型&#xff08;BFM2009&#xff09;及其他数据 运行官方 Demo训练自己的视频数据准备训练推理测试 遇到的问题与解决方案问题一&#xff1a;cuda 安装完发现版本不对问题二&#xf…

C语言 底层逻辑详细阐述结构体 #结构体的声明 #结构体的初始化 #结构体成员访问 #结构体传参

文章目录 前言 一、结构体的基础知识 二、结构体的初始化 1、结构体类型声明&#xff1a; 2、结构体成员的类型 3、结构体变量的初始化&#xff1a; 三、结构体成员访问 四、结构体传参 总结 前言 基于自我理解的角度来讲结构体&#xff1b; 一、结构体的基础知识 结构是一些…

NSSCTF中24网安培训day2中web题目

[SWPUCTF 2021 新生赛]ez_unserialize 这道题目考察php反序列化的知识点 打开题目&#xff0c;发现没有提示&#xff0c;我们试着用御剑扫描目录文件&#xff0c;发现存在robots.txt的文件 接着访问这个文件&#xff0c;发现是一段php反序列化代码&#xff0c;我们需要进行序…

论文翻译:通过云计算对联网多智能体系统进行预测控制

通过云计算对联网多智能体系统进行预测控制 文章目录 通过云计算对联网多智能体系统进行预测控制摘要前言通过云计算实现联网的多智能体控制系统网络化多智能体系统的云预测控制器设计云预测控制系统的稳定性和一致性分析例子结论 摘要 本文研究了基于云计算的网络化多智能体预…

【常见开源库的二次开发】基于openssl的加密与解密——Base58比特币钱包地址——算法分析(三)

目录&#xff1a; 目录&#xff1a; 一、base58(58进制) 1.1 什么是base58&#xff1f; 1.2 辗转相除法 1.3 base58输出字节数&#xff1a; 二、源码分析&#xff1a; 2.1源代码&#xff1a; 2.2 算法思路介绍&#xff1a; 2.2.1 Base58编码过程&#xff1a; 2.1.2 Base58解码过…

Leetcode—146. LRU 缓存【中等】(shared_ptr、unordered_map、list)

2024每日刷题&#xff08;143&#xff09; Leetcode—146. LRU 缓存 先验知识 list & unordered_map 实现代码 struct Node{int key;int value;Node(int key, int value): key(key), value(value) {} };class LRUCache { public:LRUCache(int capacity): m_capacity(capa…