Skip to content

Vue Router:前端路由、导航守卫与页面组织 ​

很多人第一次接触 Vue Router 时,最容易把它理解成:就是页面跳转用的。

这不算错,但太薄。

实际写项目时,更多是这样:Vue Router 解决的是单页应用里“URL、页面结构、组件切换、导航控制”如何稳定组织的问题。

1. 为什么 Vue 应用会需要路由 ​

如果一个应用只有一个页面,组件自己切换显示隐藏也能凑合用。

但一旦出现下面这些需求,就需要路由系统:

  1. 不同 URL 对应不同页面
  2. 浏览器前进、后退要正常工作
  3. 页面需要支持分享、刷新直达
  4. 某些页面进入前要先鉴权
  5. 页面结构需要嵌套,例如“布局 + 子页面”

这说明路由在做的,不只是“跳转”,而是 把页面结构和 URL 建立稳定映射。

2. 路由到底是什么 ​

路由可以看成 路径和页面组件之间的一套映射规则。

例如:

ts
const routes = [
  { path: '/', component: HomePage },
  { path: '/users', component: UserListPage },
  { path: '/users/:id', component: UserDetailPage }
]

这里最值得抓住的是:

  1. 路径不是随便字符串
  2. 它背后对应的是页面结构
  3. 动态参数也属于路由设计的一部分

3. Vue Router 解决什么问题 ​

3.1 页面切换 ​

它让单页应用里不同页面组件可以按 URL 切换。

3.2 URL 和页面状态对齐 ​

例如:

  1. /users
  2. /users/1001
  3. /orders?status=paid

这些地址本身就携带了页面定位信息。

3.3 导航控制 ​

它允许你在进入页面前做:

  1. 登录校验
  2. 权限判断
  3. 数据预处理

3.4 页面组织 ​

它能把:

  1. 一级页面
  2. 子页面
  3. 布局容器

组织成更稳定的结构。

4. 一个最基础的 Vue Router 示例 ​

ts
import { createRouter, createWebHistory } from 'vue-router'
import HomePage from './pages/HomePage.vue'
import UserListPage from './pages/UserListPage.vue'
import UserDetailPage from './pages/UserDetailPage.vue'

const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: '/', component: HomePage },
    { path: '/users', component: UserListPage },
    { path: '/users/:id', component: UserDetailPage }
  ]
})

export default router

然后在应用入口里挂载:

ts
app.use(router)

页面出口通常放在:

vue
<router-view />

这几段代码共同表达的是:

  1. 先定义路径和组件关系
  2. 再把路由系统装进应用
  3. 最后在页面里留出组件切换出口

这两个概念很高频。

它更适合做声明式导航。

vue
<router-link to="/users">用户列表</router-link>

5.2 router-view ​

它是当前路由对应组件的渲染出口。

vue
<router-view />

把分工拆开:

  1. router-link 负责“往哪去”
  2. router-view 负责“去哪之后显示谁”

6. params 和 query 怎么区分 ​

这是路由里最容易混的一组概念。

6.1 params ​

更适合表达:路径本身的一部分。

例如:

text
/users/1001

这里的 1001 就是路径参数。

6.2 query ​

更适合表达:筛选、排序、分页、搜索关键字这类附加条件。

例如:

text
/users?page=2&keyword=tom

6.3 更稳的记法 ​

  1. 标识“某个资源是谁”,常常更适合 params
  2. 标识“这个页面怎么筛”,常常更适合 query

7. hash 和 history 模式有什么区别 ​

7.1 hash ​

URL 会长这样:

text
/#/users

特点是:

  1. 服务端配置压力较小
  2. 兼容性理解成本低

7.2 history ​

URL 会长这样:

text
/users

特点是:

  1. 地址更自然
  2. 更符合现代应用体验
  3. 但服务端要正确处理刷新和直达

实际写项目时,更多是这样:history 模式不是纯前端问题,它还要求服务端或静态托管层把找不到的路径回退到应用入口。

8. 嵌套路由在解决什么问题 ​

嵌套路由更适合:

  1. 页面有公共布局
  2. 布局下还要切不同内容区

例如后台系统常见结构:

  1. 外层是整体布局
  2. 内层是用户页、订单页、设置页

这时路由不仅在切页面,也在表达:页面层级结构。

9. 导航守卫是什么 ​

导航守卫可以看成 在进入、离开或切换路由前后插入的一层控制逻辑。

常见用途包括:

  1. 登录校验
  2. 权限拦截
  3. 页面标题处理
  4. 埋点

9.1 一个常见示例 ​

ts
router.beforeEach((to, from, next) => {
  const token = localStorage.getItem('token')

  if (to.meta.requiresAuth && !token) {
    next('/login')
    return
  }

  next()
})

这段代码最值得先理解的是:

  1. 守卫不是业务页面本体
  2. 它更适合做页面切换前的通用控制

10. 懒加载为什么经常和路由一起出现 ​

因为路由天然是页面切分点。

例如:

ts
const UserListPage = () => import('./pages/UserListPage.vue')

这样做的价值是:

  1. 首屏不必把所有页面代码都打进去
  2. 页面切到哪,再按需加载对应代码

这会直接影响:

  1. 首屏资源体积
  2. 页面加载体验

11. 一个更贴近后台系统的路由示例 ​

ts
const routes = [
  {
    path: '/',
    component: AdminLayout,
    children: [
      { path: '', redirect: '/dashboard' },
      { path: 'dashboard', component: DashboardPage },
      { path: 'users', component: UserListPage, meta: { requiresAuth: true } },
      { path: 'orders', component: OrderListPage, meta: { requiresAuth: true } }
    ]
  },
  { path: '/login', component: LoginPage }
]

这个例子里,路由已经不只是“几个跳转地址”,而是在表达:

  1. 应用整体布局
  2. 页面层级关系
  3. 页面访问规则

12. 工程里最容易踩的坑 ​

12.1 把所有页面权限判断都写进组件里 ​

最后会导致路由层和业务层边界不清。

12.2 params 和 query 混用 ​

会让 URL 语义越来越混乱。

12.3 用路由承载太多瞬时 UI 状态 ​

不是所有局部开关都应该进 URL。

12.4 忽略 history 模式的服务端回退配置 ​

最后刷新页面时容易 404。

13. 一份检查清单 ​

当你设计 Vue Router 时,至少可以问:

  1. 这个路径是不是一个真正的页面定位
  2. 这份信息更适合放 params 还是 query
  3. 页面结构是否需要嵌套路由表达
  4. 哪些规则更适合放导航守卫
  5. 是否应该按路由做懒加载

14. 小结 ​

如果把 Vue Router 压缩成一句话,可以记住:Vue Router 不只是负责页面跳转,它负责的是单页应用里 URL、页面结构、导航控制和组件切换之间的稳定映射。

继续往下读时,再回头看 Vuex 与 Pinia 会更容易看清楚:一个在管页面结构,一个在管共享状态。

基于 VitePress 构建的个人技术笔记。