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.vue 和 src/pages/role.vue 组件,src/pages/role/index.vue 将在 src/pages/role.vue 的 <RouterView> 中渲染。
js
src/pages/
├── role/
│ └── index.vue
└── roles.vue

动态路由
- 通过用括号包裹 参数名称 来添加 路由参数,例如
src/pages/users/[id].vue将创建一个具有以下路径的路由:/users/:id - 通过用额外的一对括号包裹 参数名称 来创建 可选参数,例如
src/pages/users/[[id]].vue将创建一个具有以下路径的路由:/users/:id?。 - 通过在右括号后添加加号 (
+) 来创建 可重复参数,例如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.vue 和src/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>
