实现 前端框架 SPA 路由功能:Hash 模式与 History 模式的手动实现

前言

在前端框架(如 Vue.js、React 等)中,路由管理通常会配置一个 router 对象来定义 URL 路径与组件的映射关系。

  • 路径(path) : 这是浏览器 URL 的一部分,比如 /home 或 /about。
  • 组件(component) : 这是与该路径相关联的 Vue 组件(或其他框架的组件),如 Home.vue 或 About.vue。
    代码🌰
js 复制代码
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 哈希变化时触发,确保用户点击链接时能够更新视图。

js 复制代码
<!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 并阻止默认行为。
  • 更新浏览器历史记录并根据当前路径显示相应的内容。
  • 处理浏览器的返回按钮等历史记录操作时,重新渲染正确的内容。

如果对你有所帮助就点个关注吧,会持续更新文章

相关推荐
Linux-lucky1 小时前
45-Linux学习之旅之防火墙与WEB加固
linux·前端·网络·学习·ubuntu
Dream it possible!3 小时前
LeetCode 面试经典 150_多维动态规划_交错字符串(97_C++_中等)
算法·leetcode·面试·动态规划
心抵鹊3 小时前
算法之双指针系列(一)
算法·leetcode
风骏时光牛马3 小时前
生成一个移动端标题,只需要一个标题,不需要其他的任何文本。
前端
十二3 小时前
【洛谷题解】P1083 [NOIP 2012 提高组] 借教室(二分答案 + 差分)
数据结构·c++·算法·蓝桥杯
IT_陈寒4 小时前
Redis雪崩把我坑惨了,这是5年经验的教训
前端·人工智能·后端
SameX4 小时前
HarmonyOS ArkUI List 的侧滑删除 用 ListItem 的 swipeAction + endIcon 的做法
前端
小此方4 小时前
[算法实战论:动态规划]回文串问题的dp解法,回文串问题的母题,以及以此为基础的派生题
算法·动态规划
Pniubi5 小时前
力扣560.和为k的子数组
算法·leetcode·职场和发展
D e re k ZH5 小时前
C++ 从零入门(一):基础语法与程序结构
数据结构·c++·算法