探索Hash Router:构建单页应用的基石
前言
第一次看到Vue的路由模式的时候,有点分不清楚 createWebHashHistory()
和 createWebHistory
的区别,感觉功能也差不多。后来去搜了一下发现前面的那个叫做哈希模式,哈希模式通过URL的hash(即#后面的部分)来实现前端路由。我寻思着好像我在html里面见过这东东,找了找遗失的记忆,果然存在。和我们用来浏览器定位的锚链接相同,点击锚链接也同样会发生地址的改变,但是页面不会进行刷新。因此我查阅了一下资料。咦,原来这种使用hash路由不进行页面刷新的应用叫做SPA单页应用。
传统的HTTP协议是无状态的,这意味着服务器端在完成一次请求响应后,并不能主动向客户端推送内容,每次请求新的资源,如从/page1跳转到/page2,都需要浏览器重新发送请求,服务器返回完整的HTML文档。这不仅增加了网络负担,也让用户在等待页面加载时体验不佳。
而单页应用的出现,彻底改变了这一现状。通过前端路由技术,如Hash Router,我们能够在不重新加载整个页面的情况下,实现页面内容的动态替换,仅仅通过修改URL的哈希值(即URL中#后面的部分),就能模拟页面跳转,从而实现无刷新的页面过渡,极大地提升了用户体验。
Hash Router的工作原理
Hash Router的核心在于监听URL的哈希值变化,即hashchange
事件。这个事件是浏览器原生的JS事件,无论是否使用 Vue.js 或其他框架。当浏览器的 URL 的 hash(即 URL 中 #
后面的部分)发生变化时,会触发 hashchange
事件。当用户点击链接或通过JavaScript操作改变URL的哈希部分时,浏览器会触发此事件,而不会重新加载页面。Hash Router利用这一特性,根据不同的哈希值加载相应的组件或视图,更新页面内容。我们可以进行自己的手写一个简单的基于哈希(hash)的路由系统,来实现一下hash 路由的使用。
路由系统实现
HTML结构
<nav id="nav"><ul><li><a href="#/page1">page1</a></li><li><a href="#/page2">page2</a></li><li><a href="#/page3">page3</a></li></ul>
</nav>
<div id="container"></div>
这里定义了一个导航菜单,包含三个链接,分别指向不同的哈希路径(#/page1
, #/page2
, #/page3
)。<div id="container">
作为内容展示区域,将根据路由变化动态更新其内容。大家可以先创建一个html将内容复制然后点击查看一下url路径的改变和页面有无进行刷新
HashRouter 类进行路由管理
class HashRouter {constructor() {this.routes = {};//page => Component// window.addEventListener('hashChange', this.load.bind(this), false)window.addEventListener('hashchange', () => {this.load();}, false)}register(hash, callback = function () { }) {this.routes[hash] = callback;}registerIndex(callback = function () { }) {this.routes['index'] = callback;}load() {console.log(location.hash);let hash = location.hash.slice(1);//去掉# 方是路由console.log(hash);if (!hash) {//首页this.routes['index'] && this.routes['index'].call(this);} else {//相应页面this.routes[hash] && this.routes[hash].call(this);}}}
- 构造函数:初始化路由对象,并监听
hashchange
事件,当哈希值改变时,调用load
方法。 - register方法:允许用户注册一个哈希路径和对应的处理函数。
- registerIndex方法:特化处理首页逻辑,确保没有哈希时显示首页。
- load方法:根据当前哈希值查找路由表,执行相应的处理函数,更新页面内容。
这里进行路由加载的时候需要特别注意需要先进行路由是否注册的判断,因为用户可能进行非法输入,但是你没有相对的路由注册,那么就会报错。所以这里我们先进行路由检查在进行路由相对应的处理函数。
路由注册与初始化
let router = new HashRouter();
router.registerIndex(() => container.innerHTML = `<h1>首页</h1>`);
router.register('/page1', () => container.innerHTML = `<h1>page1</h1>`);
router.register('/page2', function () {console.log(this, this.routes);container.innerHTML = `<h1>page2</h1>`;
});
router.register('/page3', () => container.innerHTML = `<h1>page3</h1>`);
console.log(router.routes);
router.load();
- 创建实例:创建
HashRouter
的实例router
。 - 注册路由:分别注册了首页和其他页面的路由处理逻辑,当路由被命中时,会将
container
的innerHTML
替换为对应页面的内容。 - 初始化加载:手动调用
router.load()
进行首次页面加载,展示当前哈希对应的页面内容。
初始化加载主要是进行路由分享进来的用户可以直接定位当前路由展示的页面组件
总结
这段代码通过定义一个简单的HashRouter
类,实现了基本的单页应用路由功能。当用户点击导航链接改变URL哈希时,会触发页面内容的无刷新更新。通过直接操作DOM(即container.innerHTML
)来展示不同页面,是早期SPA开发的一种常见模式,虽然简单但直观展示了SPA路由的核心原理。随着框架如Vue Router的发展,现代SPA应用更多采用组件化的路由管理,但理解这段基础逻辑对于深入学习前端路由机制非常有帮助。
本次文章就分享到这里了,喜欢的话就点个关注和赞吧- ̗̀(๑ᵔ⌔ᵔ๑)。
相关文章:
探索Hash Router:构建单页应用的基石
前言 第一次看到Vue的路由模式的时候,有点分不清楚 createWebHashHistory()和 createWebHistory的区别,感觉功能也差不多。后来去搜了一下发现前面的那个叫做哈希模式,哈希模式通过URL的hash(即#后面的部分)来实现前端…...
MySQL中undo log、redo log 和 binlog三种日志的作用及应用场景
在 MySQL 数据库中,undo log、redo log 和 binlog 都是关键的日志类型,它们在数据恢复和事务管理中起着重要作用。 Undo Log(回滚日志) 作用:undo log 主要用于事务回滚和MVCC(多版本并发控制)。…...

javaweb零碎知识3
// 假设您已经导入了 axios import axios from axios;// 获取表单元素 const form document.getElementById(myForm);// 为表单添加 submit 事件监听器 form.addEventListener(submit, function(e) {// 阻止表单的默认提交行为e.preventDefault();// 创建 FormData 对象并从表…...

2024.7.9.小组汇报postman分享会
文章目录 一、前言(一)界面导航说明(二)发送第一个请求 二、基本功能(一)常见类型的接口请求(常见的接口有如下四种类型:1.查询参数的接口请求2.表单类型的接口请求3.上传文件的表单请求4.JSON …...
C语言文件操作-文件IO(系统调用)
文件IO (系统调用) 文件描述符open函数read函数write函数lseek函数close函数dup函数dup2函数 stat函数getpwuid函数getgrgid函数 实例 目录操作 opendir函数readdir函数rewinddir函数closedir函数实例 文件IO (系统调用) 文件IO就是系统调用,用户空间进入内核空间…...

LeetCode67(二进制求和[位运算,大数运算])
二进制求和 题目要求: 给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。 这道题其实有几种解法.我们先来介绍简单的方法. 我们可以将两个字符串的二进制转成十进制,获取对应值相加之后,我们可以不断对2取余,获取尾数拼接即可.也就是像我们平常求一…...

grep对文件内容搜索(附重要拓展-正则表达式)
文件搜索是搜索查找符合条件的某文件的目录,若要编辑文件或对文件的某配置进行修改,就需要对文件内容进行搜索。 grep 命令是 Linux 及类 Unix 操作系统中的一个强大的文本搜索工具,用于搜索一个或多个文件中匹配给定模式的行。grep 代表“Gl…...

前端JS特效第26波:jQuery日期时间选择器插件
jQuery日期时间选择器插件,先来看看效果: 部分核心的代码如下: <!DOCTYPE html> <html> <head lang"zh-CN"> <meta charset"UTF-8"> <title>jQuery日期时间选择器插件 - PHP中文网</t…...

Anaconda+Pycharm 项目运行保姆级教程(附带视频)
最近很多小白在问如何用anacondapycharm运行一个深度学习项目,进行代码复现呢?于是写下这篇文章希望能浅浅起到一个指导作用。 附视频讲解地址:AnacondaPycharm项目运行实例_哔哩哔哩_bilibili 一、项目运行前的准备(软件安装&…...
java面试-java基础(上)
文章目录 一、什么是Java?特点?二、什么是JVM、JDK、JRE?三、java跨平台实现原理四、java数据类型有哪些?五、char能不能存一个中文汉字?六、存在数字i加1小于i或者i减1小于i?七、什么是自动类型转换与强制类型转换?八、什么是装/拆箱&am…...

STM32快速搭建项目框架
注:编写本博客的原因,学习期间基于复习之前知识点的需要,故撰写本教程,即是复习前面的知识点也是作为博客的补充 1.0 文件夹的创建 创建一个STM32项目为模版工程,问价夹下分别包含4个子文件夹,一个是Librar…...

JMH324-免费【最后一战LOL】MOBA竞技版本+单机一键端+视频教程+文本教程
资源介绍: 修改前打开【D:\ZHServer】文件夹里的【[1]一键启动.bat】,游戏不要打开,否则修改失败。 修改完以后重启架设程序才会生效。 fball_gamedb1数据库——gameuser数据表 obj_name 角色名 obj_lv 等级 obj_diamond 钻石 obj_gold 8…...

WPF UI 3D 多轴 机械臂 stl 模型UI交互
1、三维插件环境调整 2、动态模型材质处理 3、动态模型鼠标交互 4、模型旋转基本思路 5、六轴机械臂节点旋转处理 6、更多HelixToolkit插件处理案例 7、快速对接Blender模型 鼠标交互(没有强调场景的变换) 鼠标命中测试(HitTest 不推荐&…...

《金山 WPS AI 2.0:重塑办公未来的智能引擎》
AITOP100平台获悉,在 2024 世界人工智能大会这一科技盛宴上,金山办公以其前瞻性的视野和创新的技术,正式发布了 WPS AI 2.0,犹如一颗璀璨的星辰,照亮了智能办公的新征程,同时首次公开的金山政务办公模型 1.…...

RT2-使用NLP的方式去训练机器人控制器
目标 研究在网络数据上训练的视觉语言模型也可以直接结合到端到端的机器人控制中,提升泛化性以及获得突出的语义推理;使得单个的端到端训练模型可以同时学习从机器人观测到动作的映射,这个过程可以受益于基于网络上的语言和视觉语言数据的预训…...
VisActor vs ECharts: 哪个更适合你的数据可视化需求?
VisActor vs ECharts: 哪个更适合你的数据可视化需求? 在当今数据驱动的世界里,选择合适的数据可视化工具是至关重要的。ECharts作为广受欢迎的可视化库,已经在行业内拥有了长久的历史和广泛的用户基础。然而,VisActor作为新兴的…...

【QT中实现摄像头播放、以及视频录制】
学习分享 1、效果图2、camerathread.h3、camerathread.cpp4、mainwindow.h5、mainwindow.cpp6、main.cpp 1、效果图 2、camerathread.h #ifndef CAMERATHREAD_H #define CAMERATHREAD_H#include <QObject> #include <QThread> #include <QDebug> #include &…...

el-table封装popver組件,点击列筛选行数据功能,支持筛选,搜索,排序功能
子组件: <template><div class"tableTool" ref"tableTool" click.stop><el-button click"shengFnc">升序</el-button><el-button click"jiangFnc">降序</el-button><el-input v-m…...

基于DPU的云原生计算资源共池管理解决方案
1. 方案背景和挑战 在传统的云环境中,通常存在着不同的技术栈,支撑多样化的计算服务,具体如下: ① OpenStack环境与虚拟化云主机及裸金属服务 OpenStack是一个开源的云计算管理平台项目,它提供了部署和管理大规模计…...
Bugly并非无所不能
在 iOS 应用因为内存占用过大而被系统 killed 的情况下,Bugly 以及大多数崩溃报告工具是无法捕获到这种类型的崩溃信息的。原因在于,当系统由于内存压力过大而终止应用时,是直接将应用进程杀死,不会触发常规的崩溃处理流程&#x…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...