vue-router 5.x 文件式路由

Vue Router 内置了基于文件的路由插件。会自动根据页面组件生成路由和类型,因此不再需要手动维护 routes 数组。

项目中使用文件式路由

src/router/index.ts

js 复制代码
import { createRouter, createWebHistory } from 'vue-router'
// 自动生成的路由(vite 插件注入)
import { routes } from 'vue-router/auto-routes'

console.log('routes', routes)
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes,
})

router.afterEach((to, from) => {
  document.title = to.meta.title ? `${to.meta.title} |Vite Vue3 平台 ` : 'Vite Vue3 平台'
})

export default router

vite.config.ts

js 复制代码
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import vueDevTools from 'vite-plugin-vue-devtools'
import VueRouter from 'vue-router/vite'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    // 必须要在 vue 插件之前
    VueRouter({
      routesFolder: 'src/pages', // 默认 pages
      extensions: ['.vue'], // 匹配文件后缀
      dts: 'src/typed-router.d.ts', // 生成类型文件

       // 添加调试选项
      logs: true,

      // routeBlockLang: 'json5', // 路由块语言,默认 json
      importMode: 'async',
      root: process.cwd(),

      // 在配置文件写入前,手动修改路由配置(如添加全局路由守卫、调整路由元信息、过滤路由等)
      // beforeWriteFiles: (editedRoutes) => {
      //   console.log('beforeWriteFiles', editedRoutes)
      // },
      watch: true, // 开启路由块文件监听
      // 开启实验性功能
      experimental: {
        
      },
    }),
    vue(),
    vueJsx(),
    vueDevTools(),
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    },
  },
})

默认情况下,此插件会检查 src/pages 文件夹中的任何 .vue 文件,并根据文件名生成相应的路由结构。

vue-router/vite 插件有哪些 options 配置?

js 复制代码
/**
 * vue-router plugin options.
 */
export interface Options {
  /**
   * Extensions of files to be considered as pages. Cannot be empty. This allows to strip a
   * bigger part of the filename e.g. `index.page.vue` -> `index` if an extension of `.page.vue` is provided.
   * 
   * 识别为路由页面的文件后缀(不能为空)
   * @default `['.vue']`
   */
  extensions?: string[]

  /**
   * Folder(s) to scan for files and generate routes. Can also be an array if you want to add multiple
   * folders, or an object if you want to define a route prefix. Supports glob patterns but must be a folder, use
   * `extensions` and `exclude` to filter files.
   * 
   * 扫描路由文件的目录(支持多目录 / 前缀)
   *
   * @default `"src/pages"`
   */
  routesFolder?: RoutesFolder

  /**
   * Array of `picomatch` globs to ignore. Note the globs are relative to the cwd, so avoid writing
   * something like `['ignored']` to match folders named that way, instead provide a path similar to the `routesFolder`:
   * `['src/pages/ignored/**']` or use `['**​/ignored']` to match every folder named `ignored`.
   * 
   * 排除的文件 / 目录
   * @default `[]`
   */
  exclude?: string[] | string

  /**
   * Pattern to match files in the `routesFolder`. Defaults to `*\/*` plus a
   * combination of all the possible extensions, e.g. `*\/*.{vue,md}` if
   * `extensions` is set to `['.vue', '.md']`. This is relative to the {@link
   * RoutesFolderOption['src']} and
   * 
   * 匹配的文件模式
   *
   * @default `['*\/*']`
   */
  filePatterns?: string[] | string

  /**
   * Method to generate the name of a route. It's recommended to keep the default value to guarantee a consistent,
   * unique, and predictable naming.
   * 自定义路由名称生成逻辑
   */
  getRouteName?: (node: TreeNode) => string

  /**
   * Allows extending a route by modifying its node, adding children, or even deleting it. This will be invoked once for
   * each route.
   * 
   * 扩展 / 修改单个路由(增删改属性)
   *
   * @param route - {@link EditableTreeNode} of the route to extend
   */
  extendRoute?: (route: EditableTreeNode) => _Awaitable<void>

  /**
   * Allows to do some changes before writing the files. This will be invoked **every time** the files need to be written.
   *
   * 写入路由文件前修改整体路由树
   * @param rootRoute - {@link EditableTreeNode} of the root route
   */
  beforeWriteFiles?: (rootRoute: EditableTreeNode) => _Awaitable<void>

  /**
   * Defines how page components should be imported. Defaults to dynamic imports to enable lazy loading of pages.
   * 
   * 页面组件的导入方式(同步 / 异步)
   * @default `'async'`
   */
  importMode?: 'sync' | 'async' | ((filepath: string) => 'sync' | 'async')

  /**
   * Root of the project. All paths are resolved relatively to this one.
   * 
   * 项目根目录(所有路径相对此目录)
   * @default `process.cwd()`
   */
  root?: string

  /**
   * Language for `<route>` blocks in SFC files.
   * SFC 中 <route> 块的解析语言
   * @default `'json5'`
   */
  routeBlockLang?: 'yaml' | 'yml' | 'json5' | 'json'

  /**
   * Should we generate d.ts files or ont. Defaults to `true` if `typescript` is installed. Can be set to a string of
   * the filepath to write the d.ts files to. By default it will generate a file named `typed-router.d.ts`.
   * 是否生成类型文件(指定路径)
   * @default `true`
   */
  dts?: boolean | string

  /**
   * Allows inspection by vite-plugin-inspect by not adding the leading `\0` to the id of virtual modules.
   * 兼容 vite-plugin-inspect 调试
   * @internal
   */
  _inspect?: boolean

  /**
   * Activates debug logs.
   * 开启调试日志(查看路由生成过程)
   */
  logs?: boolean

  /**
   * @inheritDoc ParseSegmentOptions
   */
  pathParser?: ParseSegmentOptions

  /**
   * Whether to watch the files for changes.
   *
   * Defaults to `true` unless the `CI` environment variable is set.
   * 监听文件变化自动更新路由
   * @default `!process.env.CI`
   */
  watch?: boolean

  /**
   * Experimental options. **Warning**: these can change or be removed at any time, even it patch releases. Keep an eye
   * on the Changelog.
   */
  experimental?: {
    /**
     * (Vite only). File paths or globs where loaders are exported. This will be used to filter out imported loaders and
     * automatically re export them in page components. You can for example set this to `'src/loaders/**\/*'` (without
     * the backslash) to automatically re export any imported variable from files in the `src/loaders` folder within a
     * page component.
     * 自动导出数据加载器
     */
    autoExportsDataLoaders?: string | string[]

    /**
     * Enable experimental support for the new custom resolvers and allows
     * defining custom param matchers.
     * 自定义路径解析规则(如参数命名、可选参数标识)
     */
    paramParsers?: boolean | ParamParsersOptions
  }
}

实现 404 页面

要创建通配符路由,需要参数名称前添加 3 个点 (...),例如 src/pages/[...path].vue 将创建一个具有以下路径的路由:/:path(.*)。这将匹配任何路由。

src/pages/[...path].vue

js 复制代码
<template>
  <div class="not-found-container">
    <div class="not-found-content">
      <div class="error-code">
        <span class="digit">4</span>
        <span class="digit">0</span>
        <span class="digit">4</span>
      </div>
      <h1 class="error-title">页面不存在</h1>
      <p class="error-description">抱歉,您访问的页面可能已被删除、移动或输入了错误的地址。</p>
      <router-link to="/home" class="back-home-btn"> 返回首页 </router-link>
    </div>
  </div>
</template>

<script lang="ts" setup>
defineOptions({
  name: 'NotFoundView',
})
</script>

嵌套路由

嵌套路由是通过在文件夹旁边定义一个 .vue 文件同名的 来自动定义的。如果创建了 src/pages/role/index.vuesrc/pages/role.vue 组件,src/pages/role/index.vue 将在 src/pages/role.vue<RouterView> 中渲染。

js 复制代码
src/pages/
├── role/
│   └── index.vue
└── roles.vue

动态路由

  1. 通过用括号包裹 参数名称 来添加 路由参数,例如 src/pages/users/[id].vue 将创建一个具有以下路径的路由:/users/:id
  2. 通过用额外的一对括号包裹 参数名称 来创建 可选参数,例如 src/pages/users/[[id]].vue 将创建一个具有以下路径的路由:/users/:id?
  3. 通过在右括号后添加加号 (+) 来创建 可重复参数,例如 src/pages/articles/[slugs]+.vue 将创建一个具有以下路径的路由:/articles/:slugs+

可选参数 src/pages/home/user.create.[[id]].vue

命名视图

通过在文件名后附加 @ + 名称来定义 命名视图

src/pages/home/dashboard.vu

js 复制代码
<template>
  <div>
    <router-view />
    <router-view name="logs" />
  </div>
</template>
<script lang="ts" setup>
defineOptions({
  name: "HomeDashboardView",
});
</script>

src/pages/home/dashboard.vue 会渲染src/pages/home/dashboard/index.vuesrc/pages/home/dashboard/index@logs.vue组件的内容。

路由组

路由组 (Route Groups)是一个用于纯粹组织代码 的功能:用 () 包裹的文件夹名称不会出现在最终的路由路径中,可以按功能或模块自由归类页面文件,而不影响 URL 结构。

简单来说,路由组就是不会出现在 URL 中的文件夹 。它的语法是在文件夹名称外加上括号,例如 (admin)

组件内如何修改路由配置?

直接在页面组件文件中覆盖路由配置。插件会拾取这些更改并反映在生成的 typed-router.d.ts 文件中。

definePage

definePage() 宏修改和扩展任何页面组件。这对于添加 meta 信息或修改路由对象很有用。

js 复制代码
<script lang="ts" setup>
definePage({
  redirect: "/home",
  name: "layout",
  meta: {
    title: "Home",
  },
});
defineOptions({
  name: "IndexView",
});
</script>

SFC <route> 自定义块

默认情况下,语言是 JSON5(更灵活的 JSON 版本),但也支持 yaml、yml 和 JSON。

js 复制代码
<route lang="yaml">
name: "role_index"
</route>
js 复制代码
<route lang="json">
{
  "name": "user_details"
}
</route>

最后

  1. vue-router 官网
  2. vite8 + vue3 文件式路由 demo
相关推荐
灰太狼大大王1 小时前
2026 前端基石:HTML5 全景知识体系指南(从入门到架构师思维)
前端
始持2 小时前
第十五讲 本地存储
前端·flutter
不甜情歌2 小时前
JS 拷贝:浅拷贝 / 深拷贝原理 + 常用方法
前端·javascript
敲代码的约德尔人2 小时前
Vue 3 响应式系统完全指南:我在 4 个项目中踩坑后总结的血泪经验
前端·vue.js
Fisschl2 小时前
在 Vue 中使用 i18n 国际化
vue.js
始持2 小时前
第十四讲 网络请求与数据解析
前端·flutter
Roselind_Yi2 小时前
技术拆解:《从音频到动效:我是如何用 Web Audio API 拆解音乐的?》
前端·javascript·人工智能·音视频·语音识别·实时音视频·audiolm
和科比合砍81分2 小时前
pnpm:public-hoist-pattern[]配置
前端
我叫黑大帅2 小时前
Js常用数组处理
前端·javascript·面试