实现 前端框架 SPA 路由功能:Hash 模式与 History 模式的手动实现
前言
在前端框架(如 Vue.js、React 等)中,路由管理通常会配置一个 router
对象来定义 URL 路径与组件的映射关系。
- 路径(path): 这是浏览器 URL 的一部分,比如
/home
或/about
。 - 组件(component): 这是与该路径相关联的 Vue 组件(或其他框架的组件),如
Home.vue
或About.vue
。
代码🌰
import { createRouter, createWebHistory } from 'vue-router';
import Home from '@/components/Home.vue';
import About from '@/components/About.vue';
const routes = [{path: '/home',name: 'Home',component: Home},{path: '/about',name: 'About',component: About}
];const router = createRouter({history: createWebHistory(),routes
});export default router;
对于现代开发的项目来说,稍微复杂一点的 SPA
,都需要用到路由。而 vue-router
正是 vue
的路由标配,且 vue-router
有两种模式: hash
和 history
。
Hash模式
hash
模式是一种把前端路由的路径用井号 #
拼接在真实 url
后面的模式。当井号 #
后面的路径发生变化时,浏览器并不会重新发起请求,而是会触发 onhashchange
事件。
使用Hash模式手写实现一个简单的 SPA 路由功能:
创建了两个链接:首页
和 关于
。它们分别指向 #/home
和 #/about
,这两个链接通过哈希(#
)实现路由。
创建了一个 div
元素,ID 为 viewrouter
,用于显示根据路由变化而改变的内容。
创建一个 routes
数组,其中包含两个路由对象,每个对象有 path
和 component
属性。path
是 URL 哈希值,component
是要在视图中显示的内容。
onHashChange
函数会在哈希变化时被调用。它首先打印当前的哈希值。
遍历 routes
数组,检查当前的哈希值是否匹配路由路径。如果匹配,更新 #viewrouter
的 innerHTML
内容为相应的 component
。
DOMContentLoaded
事件在初始 HTML 文档被完全加载和解析后触发,这样可以立即显示初始内容。
hashchange
事件在 URL 哈希变化时触发,确保用户点击链接时能够更新视图。
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>#viewrouter{width:100px;height:100px;background-color: blue;}</style></head><body><a href="#/home">首页</a><a href="#/about">关于</a><div id="viewrouter"></div><script>const router = document.getElementById('viewrouter')const routes = [{path: '#/home',component: '这是首页'},{path: '#/about',component: '<p>这是关于</p>'},]const onHashChange = () => {console.log(location.hash)routes.forEach(item=> {if(item.path ===location.hash){router.innerHTML = item.component}});}window.addEventListener('DOMContentLoaded', onHashChange)window.addEventListener('hashchange',onHashChange)</script></body></html>
History模式
history API
是 H5
提供的新特性,允许开发者直接更改前端路由,即更新浏览器 URL
地址而不重新发起请求。
使用History模式手写实现一个简单的 SPA 路由功能
routes
数组定义了路由映射关系。每个路由对象包含path
(URL 路径)和component
(显示的内容)。DOMContentLoaded
事件在文档完全加载和解析后触发,onLoad
函数在此时被调用。popstate
事件在浏览器的历史记录条目改变时触发,onPopState
函数在此时被调用。- 获取所有导航链接 (
<a>
标签),并为每个链接添加点击事件监听器。 - 点击链接时,调用
e.preventDefault()
阻止默认的浏览器跳转行为。 - 使用
history.pushState()
方法更新浏览器历史记录,同时改变 URL。 - 手动调用
onPopState()
更新视图内容。 onPopState
函数根据当前location.pathname
查找匹配的路由。- 更新
routeView
元素的innerHTML
显示对应的组件内容。
通过 history.pushState
和 popstate
事件实现了一个简单的前端路由系统:
- 用户点击导航链接时,更新 URL 并阻止默认行为。
- 更新浏览器历史记录并根据当前路径显示相应的内容。
- 处理浏览器的返回按钮等历史记录操作时,重新渲染正确的内容。
如果对你有所帮助就点个关注吧,会持续更新文章
相关文章:

实现 前端框架 SPA 路由功能:Hash 模式与 History 模式的手动实现
前言 在前端框架(如 Vue.js、React 等)中,路由管理通常会配置一个 router 对象来定义 URL 路径与组件的映射关系。 路径(path): 这是浏览器 URL 的一部分,比如 /home 或 /about。组件(compone…...

去中心化的新时代:Web3技术的全球影响
随着技术的不断演进,Web3正引领互联网的去中心化新时代。相较于传统的Web1和Web2,Web3通过去中心化、区块链和智能合约等技术,正在重塑网络的运作方式。这一变革不仅提升了网络的安全性和透明度,也对全球经济、社会和文化产生了深…...

初始redis:List
列表 List 相当于数组或者顺序表。 对于List来说,两侧都可以插入和删除,时间复杂度是O(1)。 有很多的操作,比如 llen 可以获取List的长度,lrem 可以删除元素 ,lrange可以去一个字符串 , lindex可以根据下标…...

Java | Leetcode Java题解之第355题设计推特
题目: 题解: class Twitter {private class Node {// 哈希表存储关注人的 IdSet<Integer> followee;// 用链表存储 tweetIdLinkedList<Integer> tweet;Node() {followee new HashSet<Integer>();tweet new LinkedList<Integer&g…...

MVC与三层架构分层
1. 应用分层 应用分层类似公司的组织架构。我们进行项目开发时,最开始功能简单,前后端放在一起开发,但随着项目功能的复杂,项目会被前端和后端不同的团队接手,甚至更细粒度的团队。甚至后端开发也会根据功能再进行细分…...
Go语言基础--switch
在Go语言中,switch语句是一种非常强大的控制流结构,它允许一个变量的值与多个case进行比较,并根据匹配的结果执行不同的代码块。与C、C或Java中的switch不同,Go语言的switch更灵活,支持没有显式条件的switch࿰…...

【数字ic自整资料】AXI握手协议及outstanding
参考资料: ic基础|时序篇:握手协议valid和ready的时序优化_valid和ready握手信号-CSDN博客 https://zhuanlan.zhihu.com/p/365573848 1、AXI握手协议 当我们遇到时序违例时,通常采用的方式为插入寄存器(打拍)或者是…...
C++ //练习 18.13 什么时候应该使用未命名的命名空间?
C Primer(第5版) 练习 18.13 练习 18.13 什么时候应该使用未命名的命名空间? 环境:Linux Ubuntu(云服务器) 工具:vim 解释 当需要将实体限定在特定文件中,并且不会作用于不同文件…...
yum小bug
这个错误是在克隆的机子上安装mysql时,查看有无mysql发现的 [rootwebserve-2 backup] # yum list installed | grep mysql Repository cr is listed more than once in the configuration Repository fasttrack is listed more than once in the configuration 这…...

GDB的基本使用
我有话说 因为时间和精力原因,本文写的虎头蛇尾了,除了启动调试与程序执行以外只有少量截图演示,只是简单的说明。如果有需要可以联系我,我有时间的话会把演示补上,谢谢理解。 启动调试与程序执行 启动调试并传递参数…...

如何利用AI创作高质量的文章
讯飞星火 利用AI创作高质量的文章需要遵循以下步骤: 确定主题和目标受众:在开始写作之前,明确文章的主题和目标受众。这将帮助你确定文章的风格、结构和内容。 收集资料和信息:在撰写文章之前,进行充分的研究&#x…...

开源的量化交易领域平台vn.py(VeighNa)
一:vn.py(VeighNa)下的工具以及社区版和Elite版的区别 vn.py是一款广泛应用于量化交易领域的开源软件,它主要有以下用途和功能: 1. 交易系统开发框架:vn.py提供了一个完整的交易系统开发框架,可…...
选择搜索引擎进行搜索
<!DOCTYPE html> <html> <head><meta charset"utf-8"><title>选择搜索引擎进行搜索</title><script>function searchSelectedEngine() {var keyword document.getElementById(keyword).value;var engine document.getEl…...
安卓framework修改density
安卓平台,不同屏幕分辨率需要修改density值,以适配UI显示,比如字体大小等. 命令行下进入安卓SDK源码的device/目录 再根据不同芯片厂进入不同目录, 比如展锐就是 cd device/sprd, 高通是device/qcom/搜索关键字"ro.sf.lcd_density", grep -nr “ro.sf.lcd_density”…...

我们如何将数据输入到神经网络中?
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 下面我拿识别美女的例子来给大家介绍如何将美女的图片数据输入到神经网络中。 此例中,待输入的数据是一张图像。为了存储图像…...
基于python模板的药品名称识别系统设计与实现
博主介绍: 大家好,本人精通Java、Python、C#、C、C编程语言,同时也熟练掌握微信小程序、Php和Android等技术,能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验,能够为学生提供各类…...

【第五节】Win32汇编程序设计
目录 一、汇编的第一个“helloworld” 二、汇编中的标号 三、的使用 四、数据定义 五、全局变量 六、局部变量 七、结构体 八、结构体的访问 九、获取变量地址 十、函数 十一、分支与循环 十二、内联汇编 十三、裸函数的使用 一、汇编的第一个“helloworld” .38…...

2.1算法的时间复杂度与空间复杂度
本篇博客介绍算法的时间复杂度与空间复杂度 一、算法效率 算法好坏从时间和空间两个维度衡量 二、时间复杂度 1.概念 时间复杂度是算法中基本操作的执行次数,定量描述了算法的运行时间 2.注意 (1)时间复杂度是偏…...

Linux VSFTP 部署与配置
一、VSFTP 简介与应用 VSFTP(Very Secure FTP Daemon)是一款功能强大、安全可靠的FTP服务器软件,广泛应用于Linux/Unix系统中。它提供了高效的文件传输服务,并具备诸多安全特性,如用户认证、权限控制、SSL/TLS加密等。…...

【Docker】Docker Consul
docker consul Docker Consul 是一个用于服务发现和配置的开源工具,它是 HashiCorp 公司推出的一个项目。Consul 提供了一个中心化的服务注册和发现系统,可以帮助开发人员轻松地在 Docker 容器和集群之间进行服务发现和配置管理。 Consul 使用基于 HTT…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...