前端架构入门:路由管理

4 阅读6分钟

我们来探讨前端架构中的另一个核心部分:路由管理 (Routing Management)

什么是前端路由?

在传统的 Web 应用中,每个 URL 通常对应服务器上的一个 HTML 文件或一个服务端路由处理程序。用户每次点击链接或在地址栏输入新 URL 时,浏览器都会向服务器发送请求,服务器返回新的页面。

而在单页应用 (Single-Page Application - SPA) 中,应用通常只在初始加载时从服务器获取一个 HTML 文件以及必要的 JavaScript 和 CSS。之后,当用户与应用交互,需要切换“页面”时,前端路由系统会拦截浏览器的导航行为(如点击链接或前进/后退按钮),在不重新向服务器请求整个页面的情况下,动态地更新 URL,并根据新的 URL 渲染对应的组件视图。

为什么需要路由管理?

前端路由管理对于构建用户体验良好、结构清晰的 SPA至关重要:

  1. 用户体验 (User Experience)
    • 无刷新切换:页面切换速度快,没有白屏等待,体验更接近原生应用。
    • 有意义的 URL:每个视图都有一个唯一的 URL,方便用户收藏、分享链接,并通过浏览器历史记录进行前进/后退。
    • 状态保持:刷新页面或分享链接时,能根据 URL 恢复到之前的应用状态(或视图)。
  2. 代码组织 (Code Organization)
    • 将不同的功能或视图映射到不同的 URL,使得应用的结构更加清晰。
    • 促进了页面的模块化,每个路由通常对应一个或一组页面级组件 (src/views/src/pages/)。
  3. 功能实现 (Functionality)
    • 权限控制:可以在路由切换前进行检查,未登录或无权限的用户不能访问特定页面。
    • 数据预取:可以在进入某个路由前预先加载该页面所需的数据。
    • 布局管理:可以为不同的路由组配置不同的布局(如后台管理布局、用户中心布局)。

核心概念

  • 路由 (Route):一条规则,定义了 URL 路径 (Path) 与要渲染的组件 (Component) 之间的映射关系。
  • 路由器 (Router):管理路由的核心实例。它负责监听 URL 变化,匹配路由规则,并渲染相应的组件。
  • 路由表 (Route Table / Configuration):所有路由规则的集合,通常是一个数组或对象,定义了应用的导航结构。
  • 动态路由 (Dynamic Routes):包含动态片段(参数)的路由。例如,/users/:id 可以匹配 /users/123, /users/abc 等,:id 就是动态参数。组件可以通过路由参数获取这个值(如 123, abc)。
  • 嵌套路由 (Nested Routes):路由可以嵌套,形成父子关系。父路由通常包含一个路由出口 (<router-view><Outlet>),用于渲染匹配到的子路由组件。常用于构建复杂的布局结构(如带侧边栏的布局)。
  • 路由参数 (Route Params):动态路由中传递的参数,如 /users/:id 中的 id
  • 查询参数 (Query Params):URL 中 ? 后面的键值对,如 /search?keyword=frontend&page=1。通常用于传递可选参数、筛选条件、分页信息等。
  • 命名路由 (Named Routes):给路由指定一个唯一的名称,可以通过名称进行导航,而不是硬编码 URL 路径,方便维护。
  • 导航守卫 / 路由守卫 (Navigation Guards / Route Guards):在路由切换的不同阶段(进入前、确认前、离开后等)执行的钩子函数。这是实现权限控制、数据预取、用户确认离开等逻辑的关键。你的项目中 src/accessControl.js 文件很可能就包含了导航守卫的逻辑。
  • 懒加载 / 按需加载 (Lazy Loading / On-demand Loading):只在访问某个路由时才加载对应的组件代码。这是通过代码分割 (Code Splitting) 实现的,可以显著减小初始加载的包体积,优化首屏性能。现代构建工具(如 Vite, Webpack)和路由库都原生支持。

主流路由库

  • Vue Router (Vue 官方):与 Vue.js 深度集成,提供了声明式的路由配置、导航守卫、过渡效果、滚动行为控制等丰富功能。是 Vue 项目的标准选择。你的 tdesign-template 既然是 Vue 项目,很可能使用了 vue-router
  • React Router (React 社区):React 生态中最流行的路由库,提供了基于组件的路由配置 (<Route>, <Routes>)、Hooks API (useParams, useNavigate, useLocation 等)、嵌套路由、数据加载 API 等。

路由配置实践 (src/router/)

通常,路由配置会集中在一个或多个文件中(如 src/router/index.jssrc/router/routes.js)。一个典型的配置项可能包含:

// 示例 (类似 Vue Router 的配置)
const routes = [
  {
    path: '/',
    name: 'Home',
    component: () => import('../views/HomeView.vue') // 懒加载
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('../views/AboutView.vue') // 懒加载
  },
  {
    path: '/users/:id', // 动态路由
    name: 'UserProfile',
    component: () => import('../views/UserProfile.vue'),
    props: true // 将路由参数作为 props 传递给组件
  },
  {
    path: '/admin',
    component: () => import('../layouts/AdminLayout.vue'), // 嵌套路由布局
    meta: { requiresAuth: true }, // 路由元信息,用于导航守卫判断
    children: [
      {
        path: 'dashboard',
        name: 'AdminDashboard',
        component: () => import('../views/admin/Dashboard.vue')
      },
      // ... 其他 admin 子路由
    ]
  },
  {
    path: '/:pathMatch(.*)*', // 捕获所有未匹配路径 (404)
    name: 'NotFound',
    component: () => import('../views/NotFound.vue')
  }
]

导航守卫的应用

导航守卫是实现许多路由相关逻辑的地方,例如:

  • 全局前置守卫 (beforeEach):
    • 检查用户是否登录 (访问需要认证的路由 meta: { requiresAuth: true })。如果未登录,重定向到登录页。
    • 检查用户是否有访问目标路由的权限。
    • 设置页面标题 (document.title)。
    • 记录路由访问日志。
  • 路由独享守卫 (beforeEnter): 在单个路由配置中定义,只对该路由生效。
  • 组件内守卫 (beforeRouteEnter, beforeRouteUpdate, beforeRouteLeave): 在组件内部定义,可以访问组件实例(beforeRouteUpdate, beforeRouteLeave 可以,beforeRouteEnter 不能直接访问 this,但可以通过 next(vm => ...) 访问)。常用于确认用户是否离开未保存的表单,或在路由参数变化时重新获取数据。

最佳实践

  • 使用命名路由:通过名称跳转更易维护,URL 路径变化时无需修改跳转逻辑。
  • 利用懒加载:对大部分页面级组件使用懒加载,优化性能。
  • 清晰的路由结构:对于大型应用,可以将路由配置按模块拆分。
  • 处理 404 页面:定义一个通配符路由来捕获未匹配的路径,并显示 "Not Found" 页面。
  • 利用 meta 字段:在路由配置中添加自定义元信息(如 requiresAuth, title, roles),供导航守卫使用。
  • 滚动行为控制:配置路由切换时页面的滚动位置(如切换到新页面时滚动到顶部)。

路由管理是构建结构化、用户友好的 SPA 的关键。它不仅负责视图切换,还承担了权限控制、数据加载协调等重要职责。