第 9 章:路由
学习目标
- 安装 vue-router 并注册
- 用
createRouter+createWebHistory配置 - 写
router-link/router-view - 避开历史模式和路由嵌套的 4 个坑
一、安装
bash
npm i vue-router@4二、路由配置
ts
// src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
const routes = [
{ path: '/', component: () => import('@/views/Home.vue') },
{ path: '/about', component: () => import('@/views/About.vue') },
{ path: '/user/:id', component: () => import('@/views/User.vue') },
{ path: '/:pathMatch(.*)*', component: () => import('@/views/NotFound.vue') },
]
export const router = createRouter({
history: createWebHistory(), // History 模式,无 #
routes,
})ts
// src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import { router } from './router'
createApp(App).use(router).mount('#app')⚠️ 坑 1:路由组件必须懒加载(
() => import(...)),否则首屏会下载所有页面。
三、router-link / router-view
vue
<template>
<nav>
<router-link to="/">首页</router-link>
<router-link to="/about">关于</router-link>
</nav>
<router-view />
</template><router-link> 渲染成 <a> 但不会真正刷新,默认带 .router-link-active class。
四、动态路由参数
vue
<!-- src/views/User.vue -->
<script setup lang="ts">
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.params.id) // /user/123 → id = '123'
</script>
<template>
<h1>用户 {{ route.params.id }}</h1>
</template>五、编程式导航
vue
<script setup lang="ts">
import { useRouter } from 'vue-router'
const router = useRouter()
const go = () => {
router.push('/about')
router.push({ name: 'user', params: { id: 1 } })
router.go(-1) // 后退
}
</script>六、History 模式 vs Hash 模式
| 模式 | URL | 服务端配置 |
|---|---|---|
createWebHistory | /about | 需要 nginx 配置 fallback |
createWebHashHistory | /#/about | 无需特殊配置 |
ts
// nginx 配置示例
location / {
try_files $uri $uri/ /index.html;
}⚠️ 坑 2:History 模式不配 nginx,刷新页面会 404。
七、嵌套路由
ts
const routes = [
{
path: '/admin',
component: () => import('@/views/Admin.vue'),
children: [
{ path: '', component: () => import('@/views/admin/Dashboard.vue') },
{ path: 'users', component: () => import('@/views/admin/Users.vue') },
],
},
]vue
<!-- Admin.vue -->
<template>
<div>
<Sidebar />
<router-view /> <!-- 子路由出口 -->
</div>
</template>⚠️ 坑 3:嵌套时父组件必须有
<router-view />,子路由 path 不要 加/。
八、路由元信息
ts
{
path: '/admin',
component: Admin,
meta: { requiresAuth: true, title: '后台' },
}ts
router.beforeEach((to) => {
if (to.meta.requiresAuth && !isLogin()) return '/login'
})⚠️ 坑 4:
router.beforeEach必须return一个路径,否则不会拦截。
九、本章小结
| API | 作用 |
|---|---|
createRouter | 创建路由实例 |
createWebHistory | History 模式 |
router-link | 声明式导航 |
useRoute | 获取当前路由 |
useRouter | 编程式导航 |
meta | 路由元信息 |
动手练习
- 三页路由:Home / About / NotFound,用懒加载
- 产品页:动态路由
/product/:id,显示当前 id - 后台嵌套:
/admin下嵌 Dashboard / Users
下一章:第 10 章:路由进阶 →