Vue3 路由完全指南:从入门到实战,新手也能快速上手

16 阅读8分钟

Vue3 路由完全指南:从入门到实战,新手也能快速上手

在 Vue3 项目开发中,路由(Vue Router)是不可或缺的核心模块——它负责管理页面之间的跳转、实现组件的按需加载、处理路由参数传递,甚至控制页面权限。

很多刚接触 Vue3 的新手,在使用路由时总会遇到各种问题:Vue3 路由和 Vue2 有哪些区别?如何配置路由?嵌套路由怎么实现?路由守卫该怎么用?

今天这篇文章,就带你从零吃透 Vue3 + Vue Router 4(路由最新版本)的使用,从环境搭建、基础配置到进阶技巧、实战案例,每一步都有清晰示例,帮你避开坑点,快速运用到实际项目中。

一、前言:Vue3 路由的核心变化

首先明确一个重点:Vue3 必须搭配Vue Router 4.x 版本(以下简称 Vue Router),它和 Vue2 对应的 Vue Router 3.x 有一些核心差异,新手无需深究底层,但要记住这几点关键变化:

  • 不再支持 new VueRouter(),改用 createRouter() 工厂函数创建路由实例,更贴合 Vue3 的组合式 API 风格。
  • 路由模式的配置方式变化,mode: 'history' 改为 history: createWebHistory()
  • 支持组合式 API 用法,新增 useRouter()useRoute() 等钩子,替代 Vue2 中的 this.$routerthis.$route
  • 移除了 router-linktag 属性,改用custom + 插槽实现自定义标签。

接下来,我们从环境搭建开始,一步步实现 Vue3 路由的各种用法。

二、环境搭建:安装 Vue Router 4

首先确保你已经创建了 Vue3 项目(推荐使用 Vite 创建,效率更高),如果还没有创建,先执行以下命令:

// 创建 Vue3 项目(Vite)
npm create vite@latest vue3-router-demo -- --template vue
cd vue3-router-demo
npm install

// 安装 Vue Router 4(核心步骤)
npm install vue-router@4

安装完成后,我们就可以开始配置路由了。

三、基础配置:实现简单的页面跳转

Vue3 路由的配置核心分为 3 步:创建路由实例 → 定义路由规则 → 在入口文件挂载路由,下面我们一步步操作。

1. 新建路由配置文件

在项目的 src 目录下,新建 router 文件夹,然后创建 index.js 文件(路由的核心配置文件),写入以下代码:

// src/router/index.js
// 1. 引入必要的依赖
import { createRouter, createWebHistory } from 'vue-router'

// 2. 引入需要跳转的组件(页面级组件)
import Home from '../views/Home.vue'
import About from '../views/About.vue'

// 3. 定义路由规则(数组形式,每一个对象对应一个路由)
const routes = [
  {
    path: '/', // 路由路径(URL 中显示的路径)
    name: 'Home', // 路由名称(可选,用于编程式导航)
    component: Home // 路由对应的组件
  },
  {
    path: '/about',
    name: 'About',
    component: About
    // 也可以使用懒加载(推荐,优化性能)
    // component: () => import('../views/About.vue')
  }
]

// 4. 创建路由实例
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL), // 路由模式(history 模式)
  routes // 传入路由规则(等同于 routes: routes)
})

// 5. 导出路由实例(供入口文件挂载)
export default router

2. 挂载路由到 Vue 实例

打开项目入口文件 src/main.js,引入路由实例,并用 use() 方法挂载,代码如下:

// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
// 引入路由实例
import router from './router'

// 创建 App 实例,并挂载路由
createApp(App)
  .use(router) // 挂载路由
  .mount('#app')

3. 新建页面组件

src 目录下,新建 views 文件夹(用于存放页面级组件),分别创建 Home.vueAbout.vue 两个组件:

// src/views/Home.vue
<template>
  <div class="home">
    <h1>首页</h1>
    <p>这是 Vue3 路由的首页页面</p>
  </div>
</template>

// src/views/About.vue
<template>
  <div class="about">
    <h1>关于我们</h1>
    <p>这是 Vue3 路由的关于页面</p>
  </div>
</template>

4. 使用 router-link 和 router-view

路由挂载完成后,需要在App.vue 中使用两个核心组件:

  • <router-link>:用于实现路由跳转(类似 a 标签,但不会刷新页面),默认渲染为 a 标签。
  • <router-view>:用于渲染当前路由对应的组件(页面内容会显示在这里)。

修改 App.vue 代码:

// src/App.vue
<template>
  <div id="app">
    <!-- 路由导航:跳转按钮 -->
    <nav>
      <router-link to="/">首页</router-link> |
      <router-link to="/about">关于我们</router-link>
    </nav>
    
    <!-- 路由视图:渲染当前路由对应的组件 -->
    <router-view />
  </div>
</template>

<style>
/* 激活路由的样式(默认类名:router-link-active) */
.router-link-active {
  color: #42b983;
  text-decoration: none;
  font-weight: bold;
}
</style>

5. 运行测试

执行 npm run dev 启动项目,访问本地地址,点击“首页”和“关于我们”,就能实现页面无刷新跳转,并且激活的路由会显示对应样式——这就是 Vue3 路由的基础用法!

补充:路由懒加载(推荐优化)

上面的配置中,我们直接引入了 Home 和 About 组件,这种方式会在项目打包时,将所有页面组件打包到一个文件中,导致文件体积过大,影响首屏加载速度。

推荐使用路由懒加载(按需加载),只有当用户访问该路由时,才会加载对应的组件,优化首屏性能,修改路由规则如下:

// src/router/index.js
const routes = [
  {
    path: '/',
    name: 'Home',
    // 懒加载写法:箭头函数 + import()
    component: () => import('../views/Home.vue')
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('../views/About.vue')
  }
]

四、核心用法:路由参数传递

开发中经常需要在页面跳转时传递参数(比如详情页需要接收列表页的 ID),Vue3 路由支持两种常用的参数传递方式:动态路由参数查询参数

1. 动态路由参数(推荐,用于传递必填参数)

动态路由参数是将参数嵌入到路由路径中,格式为 path: '/xxx/:参数名',适用于详情页、编辑页等需要唯一标识的场景。

步骤 1:配置动态路由
// src/router/index.js
// 引入详情页组件
const routes = [
  // 其他路由...
  {
    // 动态路由:id 是参数名(可自定义)
    path: '/user/:id',
    name: 'User',
    component: () => import('../views/User.vue')
  }
]
步骤 2:跳转时传递参数

有两种跳转方式(声明式导航 + 编程式导航),分别对应参数传递:

// 1. 声明式导航(router-link):直接在 to 中拼接参数
<router-link to="/user/123">用户123</router-link>
// 或者用对象形式(推荐,更灵活)
<router-link :to="{ name: 'User', params: { id: 123 } }">用户123</router-link>

// 2. 编程式导航(useRouter):通过 push 方法传递
<script setup>
// 引入 useRouter 钩子(组合式 API)
import { useRouter } from 'vue-router'
const router = useRouter()

// 跳转并传递参数
const goToUser = () => {
  router.push({
    name: 'User', // 必须用 name 匹配,不能用 path(path 需手动拼接参数)
    params: { id: 123 }
  })
}
</script>
步骤 3:接收动态路由参数

在目标组件(User.vue)中,使用 useRoute() 钩子获取路由信息,进而获取参数:

// src/views/User.vue
<template>
  <div class="user">
    <h1>用户详情页</h1>
    <p>用户 ID:{{ $route.params.id }}</p> 
   <!-- 或者用组合式 API(推荐) -->
    <p>用户 ID:{{ route.params.id }}</p>
  </div>
</template>

<script setup>
// 引入 useRoute 钩子,获取当前路由信息
import { useRoute } from 'vue-router'
const route = useRoute()

// 打印参数(可在生命周期或方法中使用)
console.log(route.params.id) // 输出:123
</script>

2. 查询参数(用于传递可选参数)

查询参数类似 GET 请求的参数,格式为path?key=value&key2=value2,适用于筛选、搜索等可选参数场景,不需要修改路由配置。

步骤 1:跳转时传递查询参数
// 1. 声明式导航
<router-link to="/search?keyword=vue3&page=1">搜索 Vue3</router-link>
// 或者用对象形式(推荐)
<router-link :to="{ 
  path: '/search', 
  query: { keyword: 'vue3', page: 1 } 
}">搜索 Vue3</router-link>

// 2. 编程式导航
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()

const goToSearch = () => {
  router.push({
    path: '/search',
    query: { keyword: 'vue3', page: 1 }
  })
}
</script>
步骤 2:接收查询参数

接收方式和动态路由参数类似,通过 route.query 获取:

// src/views/Search.vue
<template>
  <div class="search">
    <h1>搜索页</h1>
    <p>搜索关键词:{{ route.query.keyword }}</p>
    <p>当前页码:{{ route.query.page }}</p>
  </div>
</template>

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

console.log(route.query) // 输出:{ keyword: 'vue3', page: '1' }
</script>
两种参数的区别(重点)
参数类型URL 显示是否需要配置路由页面刷新后是否保留适用场景
动态路由参数/user/123(嵌入路径)是(需配置 :id)必填参数(详情页 ID)
查询参数/search?keyword=vue3(拼接在路径后)可选参数(筛选、搜索)

五、进阶用法:嵌套路由、路由守卫

掌握基础用法后,我们来看两个开发中高频使用的进阶技巧:嵌套路由和路由守卫。

1. 嵌套路由(多级路由)

嵌套路由用于实现页面的多级导航(比如首页下有“推荐”“热门”两个子页面),核心是在父路由中添加 children数组,配置子路由规则。

示例:实现首页嵌套子路由
// src/router/index.js
const routes = [
  {
    path: '/',
    name: 'Home',
    component: () => import('../views/Home.vue'),
    // 子路由(嵌套路由)
    children: [
      {
        path: '', // 子路由默认路径(访问 / 时,默认显示该子组件)
        name: 'HomeRecommend',
        component: () => import('../views/HomeRecommend.vue')
      },
      {
        path: 'hot', // 子路由路径(完整路径:/hot)
        name: 'HomeHot',
        component: () => import('../views/HomeHot.vue')
      }
    ]
  }
]

然后在父组件(Home.vue)中,添加 <router-view> 渲染子路由组件:

// src/views/Home.vue
<template>
  <div class="home">
    <h1>首页&lt;/h1&gt;
    <!-- 子路由导航 -->
    <div class="sub-nav">
      <router-link to="/">推荐</router-link> |
      <router-link to="/hot">热门</router-link>
    &lt;/div&gt;
    <!-- 子路由视图:渲染子路由对应的组件 -->
    <router-view />
  </div>
</template>

此时访问 /,会显示 Home 组件 + HomeRecommend 组件;访问 /hot,会显示 Home 组件 + HomeHot 组件,实现多级导航。

2. 路由守卫(路由拦截)

路由守卫用于在路由跳转前、跳转后执行一些逻辑(比如权限判断、页面埋点、取消请求),Vue Router 4 支持 3 种常用守卫:全局守卫路由独享守卫组件内守卫

(1)全局守卫(影响所有路由)

在路由配置文件中定义,适用于全局权限控制(比如未登录禁止访问个人中心):

// src/router/index.js
const router = createRouter({ ... })

// 1. 全局前置守卫(跳转前执行,最常用)
router.beforeEach((to, from, next) => {
  // to:即将跳转的路由信息
  // from:当前要离开的路由信息
  // next():放行;next('/login'):强制跳转;next(false):取消跳转
  
  // 示例:未登录禁止访问 /user
  const isLogin = localStorage.getItem('token') // 模拟登录状态
  if (to.path === '/user' && !isLogin) {
    // 未登录,强制跳转到登录页
    next('/login')
  } else {
    // 已登录,放行
    next()
  }
})

// 2. 全局后置守卫(跳转后执行,用于埋点、修改页面标题)
router.afterEach((to, from) => {
  // 修改页面标题
  document.title = to.name || 'Vue3 路由演示'
  // 页面埋点(示例)
  console.log(`跳转至:${to.path}`)
})

export default router
(2)组件内守卫(影响当前组件)

在组件内部定义,适用于当前组件的路由拦截(比如离开组件时提示保存),Vue3 组合式 API 中使用onBeforeRouteEnteronBeforeRouteLeave 等钩子:

// src/views/Edit.vue(编辑页)
<script setup>
import { onBeforeRouteLeave } from 'vue-router'

// 组件内守卫:离开当前组件时执行
onBeforeRouteLeave((to, from, next) => {
  // 示例:提示用户保存内容
  const isSave = confirm('内容未保存,确定要离开吗?')
  if (isSave) {
    next() // 确认离开,放行
  } else {
    next(false) // 取消离开
  }
})
</script>

六、实战案例:实现登录跳转+权限控制

结合上面的知识点,我们实现一个常见的实战场景:未登录用户访问个人中心时,自动跳转到登录页,登录成功后跳转回个人中心。

1. 配置路由

// src/router/index.js
const routes = [
  { path: '/', component: () => import('../views/Home.vue') },
  { path: '/login', name: 'Login', component: () => import('../views/Login.vue') },
  { 
    path: '/user', 
    name: 'User', 
    component: () => import('../views/User.vue'),
    meta: { requiresAuth: true } // 标记该路由需要登录权限
  }
]

// 全局前置守卫:权限控制
router.beforeEach((to, from, next) => {
  // 判断当前路由是否需要登录
  if (to.meta.requiresAuth) {
    const token = localStorage.getItem('token')
    if (token) {
      // 已登录,放行
      next()
    } else {
      // 未登录,跳转到登录页,并记录当前路由(登录后跳转回来)
      next({ name: 'Login', query: { redirect: to.path } })
    }
  } else {
    // 不需要登录,放行
    next()
  }
})

2. 登录组件(Login.vue)

// src/views/Login.vue
<template>
  <div class="login">
    <h1>登录页</h1>
    <button @click="login">模拟登录</button>
  </div>
</template>

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

const login = () => {
  // 模拟登录:存储 token
  localStorage.setItem('token', 'vue3-router-demo-token')
  
  // 获取登录前的跳转路径(如果有,就跳回去;没有就跳首页)
  const redirect = route.query.redirect || '/'
  router.push(redirect)
}
</script>

3. 个人中心组件(User.vue)

// src/views/User.vue
<template>
  <div class="user">
    <h1>个人中心</h1>
    <button @click="logout">退出登录</button>
  </div>
</template>

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

const logout = () => {
  // 模拟退出:清除 token
  localStorage.removeItem('token')
  // 跳转到登录页
  router.push('/login')
}
</script>

测试流程:访问 /user → 未登录,自动跳转到 /login?redirect=/user → 点击登录 → 跳回 /user → 点击退出登录 → 跳回 /login,完美实现权限控制!

七、避坑指南(新手必看)

  1. Vue3 必须使用 Vue Router 4.x,不能使用 3.x 版本,否则会报错(版本不兼容)。
  2. 组合式 API 中,不要在 <script setup> 中使用 this.$routerthis.$route,必须用useRouter()useRoute() 钩子。
  3. 动态路由参数跳转时,用 name匹配路由,不要用 path(用 path 会导致 params 参数失效)。
  4. 路由懒加载时,组件路径不要写错(相对路径要正确,比如 ../views/Home.vue,不要写成 ./views/Home.vue)。
  5. 嵌套路由的子路由 path 不要加 /,否则会被当作根路由(比如子路由 path 写 'hot',不要写 '/hot')。
  6. 全局前置守卫中,必须调用 next()next('/xxx')next(false),否则路由会卡住,无法跳转。

八、总结

Vue3 + Vue Router 4 的核心用法其实并不复杂,关键是掌握以下几点:

  • 基础配置:createRouter() 创建实例 → 挂载到 Vue 实例 → 用 router-linkrouter-view 实现跳转和渲染。
  • 参数传递:动态路由参数(必填)和查询参数(可选),接收用route.paramsroute.query
  • 进阶技巧:嵌套路由用 children 配置,权限控制用全局前置守卫。
  • 性能优化:路由懒加载按需加载组件,提升首屏速度。

本文涵盖了 Vue3 路由的所有高频用法,从基础到实战,每一步都有清晰示例,新手可以跟着步骤一步步操作,很快就能上手。