大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
Vue Router
这一课你将能做到
- 用
createRouter配置路由表 - 使用动态路由匹配不同参数
- 配置嵌套路由实现布局复用
- 用编程式导航跳转页面
- 使用路由守卫控制页面访问权限
- 实现路由懒加载优化性能
为什么要学
单页应用(SPA)的核心是「页面不刷新,内容切换」。Vue Router 就是管理这种切换的「交通指挥系统」。没有它,你的 Vue 应用只能是一个页面。
人话:Vue Router 就像「商场导购牌」。用户想去二楼(点击链接),导购牌指给他路线(路由匹配),到了二楼看到不同的店铺(组件渲染),全程不用出商场(页面不刷新)。
先建立图像
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: Home },
{ path: '/about', component: About },
{ path: '/user/:id', component: User }
]
})
浏览器地址栏变化 → 路由匹配 → 对应组件渲染到 <router-view>。
跟着做
步骤 1:安装与基础配置
npm install vue-router@4
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', name: 'Home', component: Home },
{ path: '/about', name: 'About', component: About }
]
})
export default router
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
createApp(App).use(router).mount('#app')
步骤 2:router-view 与 router-link
<!-- App.vue -->
<template>
<nav>
<router-link to="/">首页</router-link>
<router-link to="/about">关于</router-link>
</nav>
<router-view />
</template>
<router-link> 渲染为 <a> 标签,点击不刷新页面;<router-view> 是组件渲染出口。
步骤 3:动态路由
// router/index.js
{ path: '/user/:id', name: 'User', component: () => import('../views/User.vue') }
<!-- User.vue -->
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
// route.params.id 获取动态参数
</script>
<template>
<h1>用户 ID:{{ route.params.id }}</h1>
</template>
步骤 4:嵌套路由
// router/index.js
{
path: '/settings',
component: () => import('../views/Settings.vue'),
children: [
{ path: '', component: () => import('../views/SettingsHome.vue') },
{ path: 'profile', component: () => import('../views/SettingsProfile.vue') },
{ path: 'security', component: () => import('../views/SettingsSecurity.vue') }
]
}
<!-- Settings.vue -->
<template>
<div class="settings">
<aside>侧边栏</aside>
<main>
<router-view /> <!-- 子路由出口 -->
</main>
</div>
</template>
步骤 5:编程式导航
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
function goHome() {
router.push('/') // 字符串路径
router.push({ path: '/about' }) // 对象
router.push({ name: 'User', params: { id: 1 } }) // 命名路由
router.replace('/login') // 替换,不留历史记录
router.go(-1) // 后退
}
</script>
步骤 6:路由守卫
// router/index.js
router.beforeEach((to, from, next) => {
const isLogin = localStorage.getItem('token')
if (to.meta.requiresAuth && !isLogin) {
next('/login')
} else {
next()
}
})
{ path: '/admin', component: Admin, meta: { requiresAuth: true } }
步骤 7:路由懒加载
// 静态导入(打包进主 bundle)
import Home from '../views/Home.vue'
// 动态导入(单独 chunk,按需加载)
const About = () => import('../views/About.vue')
懒加载减少首屏加载体积,大型项目必备。
讲清楚要点
- createWebHistory vs createWebHashHistory:history 模式 URL 美观(无 #),但需要服务端配合;hash 模式兼容性好,URL 带 #。
- 动态路由参数:
:id是占位符,通过route.params.id获取。 - 嵌套路由:父路由组件中必须包含
<router-view>作为子路由出口。 - 编程式导航:
router.push添加历史记录,router.replace替换当前记录。 - 路由守卫:全局守卫
beforeEach最常用,还有路由独享守卫、组件内守卫。 - 懒加载:
() => import(...)语法,Webpack/Vite 自动代码分割。
你可能会懵的地方
-
history 模式部署后刷新 404? 服务端需要配置 fallback:所有路径都返回 index.html。Nginx 用
try_files $uri $uri/ /index.html。 -
route 和 router 的区别?
route是当前路由信息(path、params、query);router是路由器实例(push、replace、go)。 -
params 和 query 的区别? params 是路径的一部分(
/user/1),刷新后保留;query 是查询字符串(?id=1),更灵活。 -
路由守卫里 next() 必须调用吗? 必须,否则导航被阻塞。Vue Router 4 中也可以 return false 或 return 路径。
-
怎么监听路由变化? 组件内用
watch(() => route.path, ...),或onBeforeRouteUpdate守卫。
错法对照
| 错法 | 问题 | 正解 |
|---|---|---|
| 在 setup 外使用 useRoute/useRouter | 只能在 setup 或 <script setup> 中使用 | 在 setup 顶层调用 |
| history 模式直接部署到静态服务器 | 刷新 404 | 配置服务端 fallback |
嵌套路由父组件没有 <router-view> | 子路由不渲染 | 父组件必须包含 <router-view> |
路由懒加载写成 import(...) 但路径是变量 | 构建工具无法静态分析 | 路径必须是静态字符串 |
| 守卫里忘记调 next() | 页面卡死 | 每个分支都要 next() 或 return |
卡点急救
- 路由跳转空白:检查组件是否报错,检查
<router-view>是否存在。 - params 拿不到:确认路径写法
/user/:id,跳转用name+params或完整路径。 - 守卫死循环:确保守卫逻辑有出口,不要在守卫里又触发同样的导航。
面试常问
-
Vue Router 的两种模式区别? hash 模式兼容性好但 URL 丑;history 模式 URL 美观但需要服务端支持。
-
路由守卫有哪些? 全局守卫(beforeEach、beforeResolve、afterEach)、路由独享守卫(beforeEnter)、组件内守卫(beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave)。
-
怎么实现路由权限控制? 路由 meta 标记权限要求,全局守卫检查登录状态和角色,动态路由表按需加载。
自测三问
router.push和router.replace的区别?- 嵌套路由中父组件必须包含什么元素?
- history 模式部署到 Nginx 需要怎么配置?
小结一句话
Vue Router 是 SPA 的骨架,路由表定义路径与组件的映射,动态路由和嵌套路由实现复杂页面结构,守卫控制访问权限,懒加载优化性能。
延伸
- Vue Router 官方文档
- 下一课:Pinia 状态管理——defineStore、state、getters、actions。