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

前言

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

  • 路径(path) : 这是浏览器 URL 的一部分,比如 /home/about
  • 组件(component) : 这是与该路径相关联的 Vue 组件(或其他框架的组件),如 Home.vueAbout.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两种模式hashhistory

Hash模式

hash 模式是一种把前端路由的路径用井号 # 拼接在真实 url 后面的模式。当井号 # 后面的路径发生变化时,浏览器并不会重新发起请求,而是会触发 onhashchange 事件。

使用Hash模式手写实现一个简单的 SPA 路由功能:

创建了两个链接:首页关于。它们分别指向 #/home#/about,这两个链接通过哈希(#)实现路由。

创建了一个 div 元素,ID 为 viewrouter,用于显示根据路由变化而改变的内容。

创建一个 routes 数组,其中包含两个路由对象,每个对象有 pathcomponent 属性。path 是 URL 哈希值,component 是要在视图中显示的内容。

onHashChange 函数会在哈希变化时被调用。它首先打印当前的哈希值。

遍历 routes 数组,检查当前的哈希值是否匹配路由路径。如果匹配,更新 #viewrouterinnerHTML 内容为相应的 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 APIH5 提供的新特性,允许开发者直接更改前端路由 ,即更新浏览器 URL 地址而不重新发起请求

使用History模式手写实现一个简单的 SPA 路由功能
  • routes 数组定义了路由映射关系。每个路由对象包含 path(URL 路径)和 component(显示的内容)。
  • DOMContentLoaded 事件在文档完全加载和解析后触发,onLoad 函数在此时被调用。
  • popstate 事件在浏览器的历史记录条目改变时触发,onPopState 函数在此时被调用。
  • 获取所有导航链接 (<a> 标签),并为每个链接添加点击事件监听器。
  • 点击链接时,调用 e.preventDefault() 阻止默认的浏览器跳转行为。
  • 使用 history.pushState() 方法更新浏览器历史记录,同时改变 URL。
  • 手动调用 onPopState() 更新视图内容。
  • onPopState 函数根据当前 location.pathname 查找匹配的路由。
  • 更新 routeView 元素的 innerHTML 显示对应的组件内容。
通过 history.pushStatepopstate 事件实现了一个简单的前端路由系统:
  • 用户点击导航链接时,更新 URL 并阻止默认行为。
  • 更新浏览器历史记录并根据当前路径显示相应的内容。
  • 处理浏览器的返回按钮等历史记录操作时,重新渲染正确的内容。

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

相关推荐
Jonathan Star10 小时前
沉浸式雨天海岸:用A-Frame打造WebXR互动场景
前端·javascript
工业甲酰苯胺10 小时前
实现 json path 来评估函数式解析器的损耗
java·前端·json
老前端的功夫10 小时前
Web应用的永生之术:PWA落地与实践深度指南
java·开发语言·前端·javascript·css·node.js
LilySesy11 小时前
ABAP+WHERE字段长度不一致报错解决
java·前端·javascript·bug·sap·abap·alv
吃着火锅x唱着歌11 小时前
LeetCode 1128.等价多米诺骨牌对的数量
算法·leetcode·职场和发展
十八岁讨厌编程11 小时前
【算法训练营 · 补充】LeetCode Hot100(中)
算法·leetcode
橘颂TA11 小时前
【剑斩OFFER】算法的暴力美学——最小覆盖字串
算法·c/c++·就业
wearegogog12311 小时前
基于混合蛙跳算法和漏桶算法的无线传感器网络拥塞控制与分簇新方法
网络·算法
Wang's Blog12 小时前
前端FAQ: Vue 3 与 Vue 2 相⽐有哪些重要的改进?
前端·javascript·vue.js
再希12 小时前
React+Tailwind CSS+Shadcn UI
前端·react.js·ui