第9课 Vue Router 路由

第9课 Vue Router 路由

  • 为 Vue 应用配置多页面路由,包括嵌套路由
  • 掌握声明式导航(<router-link>)与编程式导航(useRouter
  • 掌握路由传参(query 和 params)
  • 使用导航守卫(beforeEach)实现登录拦截

1. 路由概念与安装

作用:根据浏览器 URL 显示不同页面组件,实现单页应用(SPA)内的多页面切换。

安装(需在项目根目录执行):

bash 复制代码
npm install vue-router@4

核心三件套

动作 文件 关键代码
创建路由表 + 路由器 src/router/index.js createRouter({ history, routes })
注册路由 src/main.js app.use(router)
路由出口 src/App.vue <router-view />

2. 基本配置

2.1 路由表 (src/router/index.js)

js 复制代码
import { createRouter, createWebHistory } from 'vue-router'
import LoginView from '../views/LoginView.vue'

const router = createRouter({
  history: createWebHistory(),  // History 模式,无 #
  routes: [
    { path: '/', redirect: '/dashboard' },
    { path: '/login', name: 'login', component: LoginView },
    { path: '/dashboard', name: 'dashboard', component: () => import('../views/DashboardView.vue') }
  ]
})

export default router

路由记录字段

  • path:URL 路径("门牌号")
  • component:对应组件("房间")
  • name:命名路由("昵称"),用于编程式跳转
  • redirect:访问 path 时自动重定向

2.2 注册路由 (main.js)

js 复制代码
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

createApp(App).use(router).mount('#app')

2.3 路由出口 (App.vue)

vue 复制代码
<template>
  <router-view />
</template>

3. 嵌套路由(主布局 + 子页面)

场景:后台系统有公共的顶部栏、侧边菜单,页面切换只改变内容区。

实现

  • 创建主布局组件 MainLayout.vue,内部也放置 <router-view />
  • 路由表配置 children,子页面的 path 不能以 / 开头
js 复制代码
// router/index.js
import MainLayout from '../layouts/MainLayout.vue'

routes: [
  { path: '/login', name: 'login', component: LoginView },  // 独立,不套主布局
  {
    path: '/',
    component: MainLayout,
    redirect: '/dashboard',
    children: [
      { path: 'dashboard', name: 'dashboard', component: () => import('../views/DashboardView.vue') },
      { path: 'users', name: 'users', component: () => import('../views/UserListView.vue') },
      { path: 'users/:id', name: 'user-detail', component: () => import('../views/UserDetailView.vue') }
    ]
  }
]
  • :id 是动态路由参数(见路由传参)
  • 子路由使用懒加载() => import(...) 可加快首屏加载

4. 声明式导航(<router-link>

用于模板中用户点击切换页面的链接。

html 复制代码
<router-link to="/dashboard" class="menu-item">首页</router-link>

特点

  • 不会触发整页刷新
  • 当前路由对应的链接会自动添加 router-link-active 类,可用于高亮样式:
css 复制代码
.menu-item.router-link-active {
  background: #4f46e5;
  color: #fff;
}

对象写法 (推荐用 name):

html 复制代码
<router-link :to="{ name: 'dashboard' }">首页</router-link>

5. 编程式导航(useRouter

在脚本中控制跳转,如登录成功后、按钮点击后。

js 复制代码
import { useRouter } from 'vue-router'
const router = useRouter()

// 跳转(添历史记录)
router.push('/dashboard')
router.push({ name: 'user-detail', params: { id: 3 } })

// 替换(不留历史记录,常用于登录成功)
router.replace({ name: 'login' })

// 前进/后退
router.back()
router.forward()

push vs replacepush 可后退,replace 不可后退。


6. 路由传参

6.1 路径参数 (params) ------ 动态路由

定义path: 'users/:id'

跳转必须用 name):

js 复制代码
router.push({ name: 'user-detail', params: { id: user.id } })

读取

js 复制代码
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.params.id)   // 注意:值是字符串

6.2 查询参数 (query)

跳转

js 复制代码
router.push({ path: '/users', query: { keyword: '张', status: '在职' } })
// URL: /users?keyword=张&status=在职

读取

js 复制代码
route.query.keyword   // '张'

对比

params query
URL形式 /users/3 /users?id=3
定义 路由表 path 中用 :id 无需额外定义
跳转语法 { name, params } { path/name, query }
刷新后丢失? 否(在 URL 里)

params 必须搭配 name 使用,不能直接用 path 传参。


7. 导航守卫(登录拦截)

全局前置守卫 beforeEach:每次路由跳转前检查,控制访问权限。

实现 (在 router/index.js 中):

js 复制代码
router.beforeEach((to, from, next) => {
  const isLogin = localStorage.getItem('isLogin') === 'true'

  if (to.path !== '/login' && !isLogin) {
    next({ name: 'login' })  // 未登录,重定向到登录页
  } else {
    next()  // 放行
  }
})

三个参数

  • to:目标路由对象
  • from:来源路由对象
  • next():放行 / 重定向

关键点

  • 登录页必须放行(to.path !== '/login'),否则会导致死循环
  • 登录成功时写入 localStorage.setItem('isLogin', 'true')
  • 退出登录时清除 localStorage.removeItem('isLogin')(并跳转)

8. 项目文件结构速查

复制代码
src/
├── main.js              # 注册路由
├── App.vue              # 一级出口
├── router/
│   └── index.js         # 路由表 + 守卫
├── layouts/
│   └── MainLayout.vue   # 主布局(公共外壳,包含二级出口)
└── views/
    ├── LoginView.vue
    ├── DashboardView.vue
    ├── UserListView.vue
    └── UserDetailView.vue

9. 常见错误排查

现象 原因 解决
页面空白,终端报错 Failed to resolve component: RouterView 未安装或未注册路由 npm install vue-router@4app.use(router)
子页面出现但无主布局(顶栏/侧栏消失) 子路由 path 以 / 开头 去掉开头的 /
params 传参后地址栏没有参数 使用 path 而非 name 改为 { name, params }
菜单点击不高亮 未正确使用 router-link-active 确保 CSS 选择器为 .menu-item.router-link-active
未登录也能访问后台 守卫未配置或 localStorage 残留旧值 添加 beforeEach,测试前清空 localStorage
守卫导致无法登录(无限重定向) 登录页也被拦截 条件中增加 to.path !== '/login'
登录后按后退回到登录页 登录跳转用了 push 改用 router.replace
详情页拿到的 id 参与计算出错 route.params.id 是字符串 使用 Number(route.params.id) 转换

核心总结

  • 路由 = 前台:根据 URL 映射组件
  • 嵌套路由 = 公共布局 + 子页面(children
  • 导航<router-link>(声明式)/ useRouter(编程式)
  • 传参query?key=val)适合筛选条件;params/users/:id)适合资源标识
  • 守卫beforeEach 做登录拦截,记住放行登录页
  • 登录成功用 replace,退出时清除登录态并跳转
相关推荐
用户059540174467 小时前
LangChain Memory 测试踩坑实录:用 pytest 自动化回归对话记忆,我折腾了整整一个周末
前端·css
kyriewen7 小时前
Claude Code后天起默认Auto模式了——我第一时间改了这6个设置
前端·ai编程·claude
风骏时光牛马8 小时前
智能赋能型AI办公一体化系统架构
前端
满栀5858 小时前
vue动态路由效果
前端·javascript·vue.js·前端框架·vue
土豆~8 小时前
文件名没后缀就打不开:前端文件预览的内容嗅探改造
前端·状态模式
Euato_Key9 小时前
全栈视野学习Cookie——理解 Cookie 的本质
前端
前端开发呀9 小时前
我的 AI 终端配置清单
前端
心运软件9 小时前
SpringBoot+ Vue校园社团管理平台的完整架构设计
vue.js·后端