🚀 Vue Router 5 文件式路由完全指南

在传统的 Vue SPA 开发中,维护庞大的 router/index.ts 文件(如 constantRoutes 数组)往往是一项繁琐的工作。

Vue Router v5 吸收了 unplugin-vue-router 的核心能力,官方原生支持了基于文件目录的自动路由(File-based Routing)。只需创建 Vue 文件,路由即可开箱即用。


一、 安装与依赖替换

如果你正在从旧版本的 unplugin-vue-router 迁移,或者在现有项目中尝鲜 v5,请先调整依赖:

# 1. 删除旧的第三方独立插件
pnpm remove unplugin-vue-router

# 2. 更新到 vue-router 5 (包含原生基于文件的路由能力)
pnpm update vue-router@5

# 3. 安装 vue-router 5
pnpm add vue-router@5

二、 核心构建配置

1. 修改 vite.config.ts

将路由插件直接从 vue-router/vite 导入,并确保它在 vue() 插件之前执行。

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// 核心变更:使用官方内置的 vite 插件
import VueRouter from 'vue-router/vite'

export default defineConfig({
  plugins: [
    VueRouter({
      // 默认监听 src/pages 目录
      routesFolder: 'src/pages',
    }),
    vue(),
  ],
})

2. 修改 tsconfig.json

为了让 TypeScript 和 Volar 完美识别自动生成的路由类型,需要更新编译选项。

{
  "compilerOptions": {
    "rootDir": "."
  },
  "vueCompilerOptions": {
    "plugins": [
      "vue-router/volar/sfc-typed-router",
      "vue-router/volar/sfc-route-blocks"
    ]
  },
  "include": [
    "./typed-router.d.ts" 
  ]
}

三、 初始化路由实例

修改你的 src/router/index.ts 文件。告别手写 routes 数组,直接导入自动生成的配置。

// 从 /auto 导入以获取完整的 TS 类型支持
import { createRouter, createWebHistory } from 'vue-router/auto'
import { routes } from 'vue-router/auto-routes'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  // 直接挂载自动生成的路由数组
  routes
})

// 路由守卫依然在这里正常配置
router.beforeEach((to, from, next) => {
  if (to.meta && to.meta.title) {
    document.title = to.meta.title as string
  }
  next()
})

export default router

四、 目录约定与实战用法

开启文件式路由后,src/pages/ 目录下的文件结构就是你的路由结构。

1. 基础路由映射

文件路径生成的路由 Path
src/pages/index.vue/ (首页)
src/pages/about.vue/about
src/pages/users/index.vue/users
src/pages/users/[id].vue/users/:id (动态路由)

2. 自定义路由配置 (Meta, Redirect)

如果需要定义 namemetaredirect,在对应的 .vue 文件中使用 <route> 块即可(需为标准 JSON 格式)。

示例:配置首页重定向到 Dashboard (src/pages/index.vue)

<template>
  <div>正在跳转...</div>
</template>

<route lang="json">
{
  "redirect": "/dashboard"
}
</route>

示例:配置页面 Meta 信息 (src/pages/dashboard/index.vue)

<template>
  <div>控制台</div>
</template>

<route lang="json">
{
  "name": "Dashboard",
  "meta": {
    "title": "仪表盘",
    "icon": "dashboard"
  }
}
</route>

五、 常见避坑指南 (Troubleshooting)

⚠️ 警告 1: No match found for location with path "/"

原因: 应用启动时默认访问 /,但 src/pages/ 目录下缺少 index.vue
解决:src/pages/ 新建 index.vue 文件,并根据需要编写内容或使用 <route> 配置重定向。

⚠️ 警告 2: Component "default" is a Promise instead of a function...

原因: 在手动合并路由时,错误地直接执行了懒加载导入。
解决: 确保手动配置的 component 是一个返回 Promise 的函数。

  • ❌ 错误:component: import('@/pages/index.vue')
  • ✅ 正确:component: () => import('@/pages/index.vue')

四下皆无人