目录

一、Vue3 路由基础配置:从入门到上手

1. 路由实例创建与挂载

2. 路由跳转的两种方式

3. 路由参数的传递与接收

二、嵌套路由:构建复杂页面结构

1. 嵌套路由配置

2. 父组件中渲染子路由

三、路由懒加载:优化项目性能

1. 动态导入方式

2. 定义命名代码块

3. defineAsyncComponent 方式

四、Vue3 路由总结


在现代前端开发中,单页应用(SPA)已成为主流架构模式,而路由系统作为 SPA 的核心基础设施,承担着页面跳转、状态管理、权限控制等关键职责。Vue3 作为当前最流行的前端框架之一,其配套的路由解决方案 Vue Router 4(以下简称 Vue Router)针对 Composition API 进行了全面优化,提供了更简洁的语法、更强大的功能和更优的性能。本文将从基础配置到高级实战,全方位解析 Vue3 路由的使用技巧与最佳实践,帮助开发者轻松构建灵活、高效、可扩展的路由系统

一、Vue3 路由基础配置:从入门到上手

1. 路由实例创建与挂载

Vue Router 4 的基础配置流程简洁清晰,核心步骤包括创建路由实例、定义路由规则、挂载到 Vue 应用。

首先,在项目 src 目录下创建 router 文件夹,新建 index.ts 文件,编写路由配置:

// src/router/index.ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
// 导入组件(可采用懒加载方式)
import Home from '@/views/Home.vue';
import About from '@/views/About.vue';

// 定义路由规则,RouteRecordRaw为类型定义,确保配置规范
const routes: Array<RouteRecordRaw> = [
  {
    path: '/', // 路由路径
    name: 'Home', // 路由名称(可选,用于编程式导航)
    component: Home, // 对应组件
    meta: {
      title: '首页', // 元信息,可存储页面标题、权限等自定义数据
      requiresAuth: false // 是否需要登录权限
    }
  },
  {
    path: '/about',
    name: 'About',
    component: About,
    meta: {
      title: '关于我们',
      requiresAuth: false
    }
  },
  // 404页面配置
  {
    path: '/:pathMatch(.*)*', // 匹配所有未定义的路由
    name: 'NotFound',
    component: () => import('@/views/NotFound.vue'), // 懒加载组件
    meta: {
      title: '页面未找到'
    }
  }
];

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

export default router;

然后,在 main.ts 中挂载路由实例:

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

const app = createApp(App);
app.use(router); // 挂载路由
app.mount('#app');

最后,在 App.vue 中使用<router-view>组件渲染路由对应的组件,<router-link>组件实现导航跳转:

<!-- src/App.vue -->
<template>
  <div class="app">
    <!-- 导航栏,router-link会被渲染为a标签,active-class指定激活样式 -->
    <nav>
      <router-link to="/" active-class="active">首页</router-link>
      <router-link to="/about" active-class="active">关于我们</router-link>
    </nav>
    <!-- 路由组件渲染出口 -->
    <router-view />
  </div>
</template>

<style scoped>
.active {
  color: #42b983;
  font-weight: bold;
  text-decoration: none;
  margin: 0 10px;
}
</style>

2. 路由跳转的两种方式

Vue Router 支持声明式导航和编程式导航两种跳转方式,满足不同场景需求。

(1)声明式导航

通过<router-link>组件实现,无需编写 JavaScript 代码,适用于静态导航场景。核心属性包括:

(1)to:指定跳转路径,支持字符串(如to="/about")或对象(如to="{ name: 'About' }");

(2)replace:跳转时替换历史记录,点击后退不会返回上一级页面;

(3)active-class:路由激活时的样式类名;

(4)exact:精确匹配路由(Vue Router 4 中默认开启精确匹配,无需手动设置)。

<!-- 字符串形式 -->
<router-link to="/about">关于我们</router-link>

<!-- 对象形式,通过name匹配路由(需路由配置中定义name) -->
<router-link :to="{ name: 'About' }">关于我们</router-link>

<!-- 带查询参数 -->
<router-link :to="{ path: '/user', query: { id: 1 } }">用户中心</router-link>

<!-- 替换历史记录 -->
<router-link to="/about" replace>关于我们</router-link>

(2)编程式导航

通过路由实例的方法实现跳转,适用于需要逻辑判断的动态导航场景。核心方法包括:

(1)push:添加新的历史记录,跳转后可通过后退返回;

(2)replace:替换当前历史记录,跳转后无法返回;

(3)go:前进或后退指定步数(如go(-1)表示后退一页)。

在 Vue3 的 setup 函数中,需通过useRouter获取路由实例:

<!-- src/views/Home.vue -->
<template>
  <button @click="goToAbout">跳转到关于我们</button>
  <button @click="goToUser">跳转到用户中心</button>
  <button @click="goBack">后退</button>
</template>

<script setup lang="ts">
import { useRouter } from 'vue-router';

const router = useRouter();

// 跳转到About页面
const goToAbout = () => {
  // 字符串形式
  router.push('/about');
  // 或对象形式
  // router.push({ name: 'About' });
};

// 跳转到User页面并携带查询参数
const goToUser = () => {
  router.push({
    path: '/user',
    query: { id: 1, name: '张三' }
  });
};

// 后退一页
const goBack = () => {
  router.go(-1);
};
</script>

3. 路由参数的传递与接收

路由参数是组件间传递数据的重要方式,Vue Router 支持两种参数类型:查询参数(query)和动态路由参数(params)。

(1)查询参数(query)

(1)特点:参数会拼接在 URL 后面,格式为?key=value,支持多个参数(用&分隔);

(2)优点:刷新页面后参数不会丢失,可用于分享链接;

(3)接收方式:通过useRoute钩子获取route.query。

<!-- 传递参数 -->
<router-link :to="{ path: '/user', query: { id: 1, name: '张三' } }">用户中心</router-link>

<!-- 接收参数 -->
<script setup lang="ts">
import { useRoute } from 'vue-router';

const route = useRoute();
// 类型断言,确保参数类型正确
const userId = route.query.id as string;
const userName = route.query.name as string;
console.log('用户ID:', userId, '用户名:', userName);
</script>

(2)动态路由参数(params)

(1)特点:参数嵌入 URL 路径中,格式为/path/:paramName,需在路由配置中声明;

(2)优点:URL 更简洁,语义化更强;

(3)注意:刷新页面后参数会丢失(需配合本地存储或后端接口);

(4)接收方式:通过useRoute钩子获取route.params。

示例:首先,在路由配置中声明动态参数:

// src/router/index.ts
const routes: Array<RouteRecordRaw> = [
  {
    path: '/user/:id', // 动态参数id
    name: 'User',
    component: () => import('@/views/User.vue'),
    meta: { title: '用户中心' }
  }
];

然后,传递和接收参数:

<!-- 传递参数 -->
<router-link :to="{ name: 'User', params: { id: 1 } }">用户中心</router-link>

<!-- 接收参数 -->
<script setup lang="ts">
import { useRoute } from 'vue-router';

const route = useRoute();
// 动态路由参数的类型为string
const userId = route.params.id as string;
console.log('用户ID:', userId);
</script>

二、嵌套路由:构建复杂页面结构

在实际项目中,页面通常包含多级导航(如顶部导航 + 侧边栏导航),此时需要使用嵌套路由来实现页面结构的层级化。嵌套路由的核心是在父路由中通过children属性定义子路由,同时在父组件中使用<router-view>渲染子组件。

1. 嵌套路由配置

以 “后台管理系统” 为例,父路由为/admin,子路由包括/admin/dashboard(仪表盘)、/admin/user-manage(用户管理):

// src/router/index.ts
const routes: Array<RouteRecordRaw> = [
  {
    path: '/admin',
    name: 'Admin',
    component: () => import('@/views/Admin.vue'), // 父组件
    meta: { requiresAuth: true }, // 需要登录权限
    children: [ // 子路由配置
      {
        path: 'dashboard', // 子路由路径(无需加/,会自动拼接父路由路径)
        name: 'Dashboard',
        component: () => import('@/views/admin/Dashboard.vue'),
        meta: { title: '仪表盘' }
      },
      {
        path: 'user-manage',
        name: 'UserManage',
        component: () => import('@/views/admin/UserManage.vue'),
        meta: { title: '用户管理' }
      },
      {
        path: '', // 子路由默认路径,访问/admin时自动跳转到此
        redirect: 'dashboard'
      }
    ]
  }
];

2. 父组件中渲染子路由

在父组件Admin.vue中,需要包含子路由的导航和渲染出口:

<!-- src/views/Admin.vue -->
<template>
  <div class="admin-container">
    <!-- 侧边栏导航(子路由导航) -->
    <aside class="sidebar">
      <router-link to="/admin/dashboard" active-class="active">仪表盘</router-link>
      <router-link to="/admin/user-manage" active-class="active">用户管理</router-link>
    </aside>
    <!-- 子路由渲染出口 -->
    <main class="content">
      <router-view />
    </main>
  </div>
</template>

<style scoped>
.admin-container {
  display: flex;
  height: 100vh;
}
.sidebar {
  width: 200px;
  background: #f5f5f5;
  padding: 20px;
}
.sidebar a {
  display: block;
  margin: 10px 0;
  text-decoration: none;
  color: #333;
}
.active {
  color: #42b983 !important;
  font-weight: bold;
}
.content {
  flex: 1;
  padding: 20px;
}
</style>

此时,访问/admin会自动跳转到/admin/dashboard,侧边栏导航点击后,子路由组件会在<main class="content">中渲染,实现了页面结构的层级化管理。

三、路由懒加载:优化项目性能

在大型项目中,若一次性加载所有路由组件,会导致初始打包体积过大,页面加载速度变慢。路由懒加载(也称代码分割)可将不同路由对应的组件分割为独立的代码块,只有当用户访问该路由时才会加载对应的代码,从而优化首屏加载性能。

Vue Router 4 支持两种路由懒加载方式:动态导入(推荐)和defineAsyncComponent(Vue3 新增)。

1. 动态导入方式

这是最常用的懒加载方式,通过 ES6 的import()语法实现,无需额外配置。

// src/router/index.ts
const routes: Array<RouteRecordRaw> = [
  {
    path: '/about',
    name: 'About',
    // 动态导入组件,打包时会分割为独立的代码块
    component: () => import('@/views/About.vue'),
    meta: { title: '关于我们' }
  },
  {
    path: '/admin',
    name: 'Admin',
    component: () => import('@/views/Admin.vue'),
    children: [
      {
        path: 'dashboard',
        component: () => import('@/views/admin/Dashboard.vue') // 子路由也支持懒加载
      }
    ]
  }
];

2. 定义命名代码块

若需将多个路由组件打包到同一个代码块中,可在import()中指定webpackChunkName(webpack 支持):

// 多个组件打包到admin chunk中
component: () => import(/* webpackChunkName: "admin" */ '@/views/admin/Dashboard.vue')

3. defineAsyncComponent 方式

Vue3 的defineAsyncComponent函数可用于定义异步组件,支持更灵活的加载配置(如加载状态、错误处理),也可用于路由懒加载。

// src/router/index.ts
import { defineAsyncComponent } from 'vue';

const routes: Array<RouteRecordRaw> = [
  {
    path: '/user',
    name: 'User',
    component: defineAsyncComponent({
      loader: () => import('@/views/User.vue'), // 加载组件
      loadingComponent: () => import('@/components/Loading.vue'), // 加载中状态组件
      errorComponent: () => import('@/components/Error.vue'), // 加载失败组件
      delay: 200, // 延迟显示加载组件(避免闪烁)
      timeout: 5000 // 超时时间,超过则显示错误组件
    })
  }
];

四、Vue3 路由总结

(1)规范路由配置:使用RouteRecordRaw类型定义路由规则,确保配置规范;为路由添加name属性,便于编程式导航;合理使用meta存储页面标题、权限等元信息。

(2)优先使用 Composition API:在 setup 函数中使用useRoute、useRouter替代this.$route、this.$router,配合 TypeScript 获得更好的类型支持。

(3)全面使用路由懒加载:对所有非首屏路由组件采用懒加载,减少初始打包体积;合理划分代码块,避免过多小体积代码块。

(4)精细化权限控制:结合路由元信息和全局守卫,实现基于角色或权限的访问控制;对无权限路由及时重定向,提升用户体验。

(5)优化路由跳转体验:使用scrollBehavior控制滚动行为;在组件内守卫中处理未保存数据的提示;为异步路由添加加载状态组件。

(6)避免路由冗余:合理使用嵌套路由简化页面结构;通过redirect处理默认路由和旧路由兼容。

(7)加强错误处理:配置 404 页面处理无效路由;在路由守卫和异步组件中处理错误场景,避免页面崩溃。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐