你不知道的前端路由实现方式与单页应用(SPA)架构模式详解

139 阅读4分钟

一、前言

本文从传统页面开发的局限,到前端路由的实现原理来详细讲解SPA架构模式。

二、传统页面开发的局限

在传统的多页面开发模式下,每次用户点击导航链接,浏览器都会向服务器请求新的 HTML 页面,整个页面会被重新加载和渲染。这种方式有以下缺点:

  • 全页刷新:每次跳转都会刷新整个页面,用户体验不佳。
  • 白屏现象:页面切换时会出现短暂的空白,影响流畅性。
  • 资源浪费:重复加载相同的资源(如 CSS、JS),增加带宽消耗。
<!-- 1.html/2.html 传统页面导航 -->
<nav>
  <ul>
    <li><a href="./1.html">Page 1</a></li>
    <li><a href="./2.html">Page 2</a></li>
  </ul>
</nav>

每次点击链接,都会重新加载页面。

三、前端路由的实现原理

1. Hash 路由

Hash 路由是最早被广泛应用于前端路由的方案。它利用 URL 的 #(哈希)部分来标识不同的页面状态。例如:http://example.com/#/about。当 # 后面的内容发生变化时,浏览器不会向服务器发起请求,也不会刷新页面,而是触发 hashchange 事件。前端可以监听这个事件,根据 hash 的值动态渲染不同的内容。

优点:

  • 实现简单,无需服务器配合。
  • 兼容性好,几乎所有浏览器都支持。

缺点:

  • URL 中会带有 #,不够美观。
  • 不利于 SEO(搜索引擎优化)。

示例代码:

window.addEventListener("hashchange", function () {
  // 根据 location.hash 渲染页面
});

2. History 路由

HTML5 引入了 History API(如 pushStatereplaceState),允许开发者在不刷新页面的情况下修改浏览器的 URL。例如:history.pushState({}, '', '/about')。这种方式可以让 URL 看起来更自然(如 /about),更接近传统多页面应用。

优点:

  • URL 更加美观、规范。
  • 更有利于 SEO(配合服务端渲染或预渲染)。

缺点:

  • 需要服务器支持:所有路由都要返回同一个 HTML 文件,否则刷新页面会 404。
  • 兼容性略低于 hash(但现代浏览器都已支持)。

示例代码:

history.pushState({}, "", "/about");
window.addEventListener("popstate", function () {
  // 根据 location.pathname 渲染页面
});

四、SPA架构模式

SPA(Single Page Application,单页应用)是一种网页应用或网站的架构模式。它的核心特点是整个应用只有一个 HTML 页面,所有的页面内容和交互都通过 JavaScript 动态加载和切换,无需每次跳转都向服务器请求新的 HTML 页面。

详解之什么叫单页面?

可见往期文章玩转智能前端:SSE配合流式输出的奥秘中有关于SSE(Server-Sent Events,服务端推送事件) 的内容,

用户访问网站时,服务器会只返回一个HTML文件,后续的页面切换与内容更新都在这个页面内通过JS完成。

SPA 的优点是什么?

页面切换快,不会出现页面切换时的短暂白屏,用户体验好。实现前后端分离,提高开发效率,更易于维护,此外,也可以实现更复杂的交互和动画效果。

SPA 的缺点是什么?

首次加载时需要下载较多的 JS 资源,首屏加载速度可能较慢,并且SEO(搜索引擎优化)难度较大,需要配合服务端渲染(SSR)或预渲染。浏览器前进/后退、刷新等行为需要特殊处理。

开发SPA主流的选择

实现SPA最常用、最流行的前端开发框架和它们路由的解决方案有以下三种:

1. React(配合 React Router)

React 是一个由 Facebook 推出的用于构建用户界面的 JavaScript 库,非常适合开发 SPA。

React Router 是 React 生态中专门用于实现前端路由的库,可以让你在单页应用中实现多页面的导航和切换。

2. Vue(配合 Vue Router)

Vue 是一个轻量级、易上手的前端框架,也非常适合开发 SPA。

Vue Router 是 Vue 官方提供的路由库,用于在 Vue SPA 项目中实现页面切换和路由管理。

3. Angular

Angular 是 Google 推出的前端框架,功能非常强大,内置了自己的路由系统,适合开发大型的 SPA 项目。

以 React Router 为例,核心思想是通过 <BrowserRouter><HashRouter> 包裹应用,使用 <Routes><Route> 声明路由规则,利用 useNavigateuseLocation 等钩子实现编程式导航和路由信息获取。 代码如下:

import React from "react";
import { BrowserRouter, Routes, Route, Link, useNavigate, useLocation } from "react-router-dom";

// 首页组件
function Home() {
  const navigate = useNavigate();
  return (
    <div>
      <h2>首页</h2>
      <button onClick={() => navigate("/about")}>跳转到关于页</button>
    </div>
  );
}

// 关于页组件
function About() {
  const location = useLocation();
  return (
    <div>
      <h2>关于页</h2>
      <p>当前路径:{location.pathname}</p>
    </div>
  );
}

// 404组件
function NotFound() {
  return <h2>页面未找到</h2>;
}

// 主应用
function App() {
  return (
    <BrowserRouter>
      <nav>
        <Link to="/">首页</Link> | <Link to="/about">关于</Link>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="*" element={<NotFound />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

参考资料: