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. paramsquery 怎么区分

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

6.1 params

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

例如:

text
/users/1001

这里的 1001 就是路径参数。

6.2 query

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

例如:

text
/users?page=2&keyword=tom

6.3 更稳的记法

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

7. hashhistory 模式有什么区别

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 paramsquery 混用

会让 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 构建的个人技术笔记。