前端学习教程-Vue Router 教程

Vue Router 是 Vue.js 官方的路由管理器,它与 Vue.js 核心深度集成,让构建单页应用(SPA)变得简单。

一、安装 Vue Router

1. 在 Vue 3 项目中安装

Vue 3 需使用 Vue Router 4+ 版本:

npm install vue-router@4 --save
# 或
yarn add vue-router@4

2. 项目结构准备

创建如下路由相关目录结构:

src/
├── router/
│   └── index.js  # 路由配置文件
├── views/        # 页面级组件
│   ├── Home.vue
│   ├── About.vue
│   └── User.vue
├── App.vue
└── main.js

二、基本配置与使用

1. 创建路由实例(router/index.js)

import { createRouter, createWebHistory } from 'vue-router'
// 导入页面组件
import Home from '../views/Home.vue'
import About from '../views/About.vue'
import User from '../views/User.vue'

// 路由规则
const routes = [
  {
    path: '/',          // 路径
    name: 'Home',       // 路由名称(可选)
    component: Home     // 对应的组件
  },
  {
    path: '/about',
    name: 'About',
    component: About
  },
  {
    path: '/user',
    name: 'User',
    component: User
  }
]

// 创建路由实例
const router = createRouter({
  history: createWebHistory(),  // 使用 HTML5 history 模式(无 # 号)
  // history: createWebHashHistory(), // 使用 hash 模式(带 # 号)
  routes  // 注入路由规则
})

export default router

2. 在 Vue 中引入路由(main.js)

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'  // 导入路由实例

// 创建应用并使用路由
createApp(App)
  .use(router)  // 安装路由插件
  .mount('#app')

3. 路由出口与导航(App.vue)

路由出口是路由组件渲染的位置,导航用于切换路由:

<template>
  <div id="app">
    <!-- 导航链接:替代 a 标签,避免页面刷新 -->
    <nav>
      <router-link to="/">首页</router-link> |
      <router-link to="/about">关于</router-link> |
      <router-link to="/user">用户中心</router-link>
    </nav>

    <!-- 路由出口:匹配的组件将在这里渲染 -->
    <router-view />
  </div>
</template>

<style>
/* 激活的导航链接会自动添加 router-link-active 类 */
router-link-active {
  color: #42b983;
  font-weight: bold;
  text-decoration: none;
}
</style>

三、核心功能详解

1. 动态路由(带参数的路由)

用于匹配动态变化的路径(如 /user/123/user/456):

// router/index.js 中添加动态路由
{
  path: '/user/:id',  // :id 是动态参数
  name: 'UserDetail',
  component: () => import('../views/UserDetail.vue')  // 懒加载组件
}

在组件中获取参数(UserDetail.vue):

<template>
  <div>
    <h2>用户详情</h2>
    <p>用户 ID: {{ $route.params.id }}</p>
  </div>
</template>

<script setup>
// 在 Composition API 中使用
import { useRoute } from 'vue-router'
const route = useRoute()
console.log('用户 ID:', route.params.id)  // 输出动态参数
</script>

2. 嵌套路由

用于实现页面内的子路由(如 /about/team/about/history):

// router/index.js 中配置嵌套路由
{
  path: '/about',
  name: 'About',
  component: About,
  // 子路由
  children: [
    {
      path: 'team',  // 相对路径,完整路径是 /about/team
      component: () => import('../views/AboutTeam.vue')
    },
    {
      path: 'history',  // 完整路径是 /about/history
      component: () => import('../views/AboutHistory.vue')
    },
    {
      path: '',  // 默认子路由(/about 时显示)
      component: () => import('../views/AboutIndex.vue')
    }
  ]
}

在父组件(About.vue)中添加子路由出口:

<template>
  <div>
    <h2>关于我们</h2>
    <!-- 子导航 -->
    <div>
      <router-link to="/about/team">团队</router-link> |
      <router-link to="/about/history">历史</router-link>
    </div>
    <!-- 子路由出口:子组件将在这里渲染 -->
    <router-view />
  </div>
</template>

3. 编程式导航

除了 <router-link>,还可以通过代码切换路由:

<template>
  <button @click="goToHome">回到首页</button>
  <button @click="goToUser(123)">查看用户 123</button>
</template>

<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()

// 跳转到首页
const goToHome = () => {
  router.push('/')  // 通过路径跳转
  // 或通过路由名称跳转(更推荐,路径变化时无需修改)
  // router.push({ name: 'Home' })
}

// 跳转到带参数的路由
const goToUser = (id) => {
  router.push({ 
    name: 'UserDetail',  // 使用路由名称
    params: { id }       // 传递参数
  })
}

// 后退/前进
const goBack = () => router.go(-1)  // 后退一页
const goForward = () => router.go(1)  // 前进一页
</script>

4. 路由参数与查询字符串

  • params:用于动态路由参数(如 /user/:id),必须在路由规则中定义
  • query:用于查询字符串(如 /search?keyword=vue),无需在路由规则中定义
// 跳转到带查询参数的路由
router.push({
  path: '/search',
  query: { keyword: 'vue', page: 1 }  // 生成 /search?keyword=vue&page=1
})

// 在组件中获取查询参数
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.query.keyword)  // 输出 'vue'

5. 路由守卫

用于控制路由的访问权限(如登录验证、权限检查),分为三类:

(1)全局守卫

影响所有路由,定义在 router/index.js 中:

// 全局前置守卫:路由跳转前执行
router.beforeEach((to, from, next) => {
  // to: 目标路由
  // from: 来源路由
  // next(): 继续跳转;next('/login'): 跳转到登录页

  // 示例:未登录禁止访问个人中心
  const isLogin = localStorage.getItem('token')
  if (to.path === '/user' && !isLogin) {
    return next('/login')  // 未登录跳转到登录页
  }
  next()  // 允许跳转
})

// 全局后置守卫:路由跳转后执行(无需调用 next())
router.afterEach((to, from) => {
  // 示例:修改页面标题
  document.title = to.meta.title || '我的应用'
})

(2)路由独享守卫

只影响当前路由,定义在路由规则中:

{
  path: '/admin',
  component: Admin,
  // 路由独享守卫
  beforeEnter: (to, from, next) => {
    // 示例:只有管理员可访问
    const role = localStorage.getItem('role')
    if (role === 'admin') {
      next()  // 允许访问
    } else {
      next('/forbidden')  // 无权限跳转到禁止页
    }
  }
}

(3)组件内守卫

在组件内部定义,控制组件的路由行为:

<script setup>
import { onBeforeRouteEnter, onBeforeRouteLeave } from 'vue-router'

// 进入组件前执行(此时组件实例还未创建,不能用 this)
onBeforeRouteEnter((to, from, next) => {
  // 可以在这里做权限检查
  next()
})

// 离开组件前执行
onBeforeRouteLeave((to, from, next) => {
  // 示例:未保存时提示
  if (confirm('数据未保存,确定离开吗?')) {
    next()
  } else {
    next(false)  // 取消跳转
  }
})
</script>

6. 路由元信息(meta)

用于存储路由的额外信息(如标题、是否需要登录):

// 定义路由元信息
const routes = [
  {
    path: '/user',
    component: User,
    meta: { 
      requiresAuth: true,  // 需要登录
      title: '用户中心'    // 页面标题
    }
  },
  {
    path: '/public',
    component: Public,
    meta: { 
      requiresAuth: false, // 无需登录
      title: '公共页面'
    }
  }
]

// 在全局守卫中使用元信息
router.beforeEach((to, from, next) => {
  // 检查是否需要登录
  if (to.meta.requiresAuth && !localStorage.getItem('token')) {
    next('/login')
  } else {
    next()
  }
})

// 在后置守卫中设置标题
router.afterEach((to) => {
  document.title = to.meta.title || '默认标题'
})

7. 路由懒加载

减少初始加载时间,只在访问路由时才加载组件:

// 普通加载(会一次性加载所有组件)
import Home from '../views/Home.vue'

// 懒加载(推荐)
const About = () => import('../views/About.vue')

// 路由配置中直接使用
const routes = [
  {
    path: '/about',
    component: () => import('../views/About.vue')  // 直接在路由中定义
  }
]

四、常见问题与最佳实践

  1. history 模式与 hash 模式的区别

    • createWebHistory():URL 无 # 号,需服务器配置支持(避免刷新 404)
    • createWebHashHistory():URL 带 # 号,无需服务器配置,兼容性更好
  2. 避免路由冗余

    • 使用路由名称(name)跳转,而非硬编码路径
    • 提取公共路由配置(如需要登录的路由可统一处理)
  3. 路由模块化:大型项目可拆分路由配置:

    // router/modules/user.js
    export default [
      { path: '/user', component: User },
      { path: '/user/:id', component: UserDetail }
    ]
    
    // router/index.js 中合并
    import userRoutes from './modules/user'
    const routes = [...userRoutes, ...otherRoutes]
    

五、总结

  • 路由的基本配置与使用
  • 动态路由、嵌套路由、编程式导航
  • 路由守卫与权限控制
  • 路由元信息与懒加载
posted @ 2025-10-04 22:34  碧水云天4  阅读(36)  评论(0)    收藏  举报