Vue 不想写路由?无需迁移 Nuxt,一个插件搞定!

2,692 阅读9分钟

一、引言

在 Vue 应用中,路由是实现页面导航的重要部分。传统上,我们需要手动配置每个路由路径和组件,随着项目规模的扩大,路由配置往往变得冗长且难以维护。尤其是在一些动态路由、嵌套路由等场景下,手写路由配置不仅繁琐,而且容易出错。

虽然 Nuxt.js 提供了自动化的路由管理机制,但将现有 Vue 项目迁移到 Nuxt 可能会带来不小的成本。其实,你不必迁移到 Nuxt,也能享受自动生成路由的便利。通过 unplugin-vue-router 插件,你可以轻松实现路由自动化生成,省去手动配置的麻烦,同时保持 Vue 的灵活性和可定制性。

本文将介绍如何使用 unplugin-vue-router 插件,简化 Vue 应用中的路由配置,实现路由自动生成,无需迁移到 Nuxt,轻松提升开发效率。

二、什么是 unplugin-vue-router

unplugin-vue-router 是大神 Eduardo 专为 Vue 应用设计的插件,旨在简化路由管理流程。它通过扫描指定的文件目录(通常是 src/pages),自动生成符合 Vue Router 标准的路由配置,从而让开发者免去手动配置路由的繁琐过程。

核心功能与优势

  • 路由自动生成:基于文件和目录结构自动创建路由,无需手写配置。
  • 动态路由支持:通过文件命名(如 [id].vue)直接实现动态路由。
  • 懒加载优化:默认支持路由组件的按需加载,提升应用性能。
  • 文件结构即路由结构:开发者只需关注组件的组织,路由管理变得更加直观。
  • 支持 TypeScript:自动生成路由类型声明文件,优化开发体验。
  • 灵活配置:提供丰富的配置选项,适配不同项目需求。

三、如何安装和使用 unplugin-vue-router

1. 安装插件

通过 npm、yarn 或者 pnpm 安装插件:

# 使用 npm
npm install unplugin-vue-router --save-dev

# 使用 yarn
yarn add unplugin-vue-router --dev

# 使用 pnpm
pnpm add unplugin-vue-router --dev

2. 安装 Vue Router

如果您的项目已经安装了 Vue Router 则这步可以忽略。

由于 unplugin-vue-router 是基于 Vue Router 工作的,需要确保项目中已安装 Vue Router。如果尚未安装,可以执行以下命令:

# 安装 Vue Router
npm install vue-router

3. 集成插件

以 Vite 项目中集成插件为例展示如何配置。

Vite 配置

vite.config.ts 文件中配置 unplugin-vue-router 插件。这里需要导入插件并添加配置项:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import VueRouter from 'unplugin-vue-router/vite'

export default defineConfig({
  plugins: [
    vue(),
    VueRouter({
      dirs: ['./src/pages'], // 默认扫描的目录,您可以自定义
      dts: './src/typed-router.d.ts', // 自动生成类型声明文件
    }),
  ],
})
  • dirs:指定插件扫描的目录(默认为 ./src/pages)。你可以根据项目需求调整。
  • dts:自动生成 TypeScript 类型声明文件,以便更好地支持类型检查。
生成类型声明

如果你希望插件生成路由类型声明文件,可以在 tsconfig.json 中添加以下配置,以确保 TypeScript 正确识别生成的类型声明:

{
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "~/*": ["src/*"]
    }
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.d.ts",
    "src/**/*.vue",
    "src/typed-router.d.ts" // 确保 TypeScript 知道类型声明文件的位置
  ]
}

如果你的项目已经包含了 env.d.ts 文件(通常在使用 npm vue create <my-project> 创建项目时会自动生成),你只需要在该文件中添加以下内容,以便引入 unplugin-vue-router 插件的类型:

/// <reference types="vite/client" />
/// <reference types="unplugin-vue-router/client" />
  • vite/client 类型会在你创建 Vite + Vue 项目时自动添加,而添加 unplugin-vue-router/client 可以确保 TypeScript 正确识别插件提供的类型。

如果你没有 env.d.ts 文件,你可以直接在 tsconfig.json 中添加 unplugin-vue-router 的类型,方法如下:

{
  "compilerOptions": {
    // ...
    "types": [
      "unplugin-vue-router/client"
    ]
  }
}

4. 自动生成的 routes 配置到 vue-router

unplugin-vue-router 会根据 src/pages 目录中的 Vue 文件结构自动生成路由配置。例如,假设你的项目中有如下目录结构:

src/
├── pages/
│   ├── index.vue         // 对应 "/"
│   ├── about.vue         // 对应 "/about"
│   ├── user/
│       ├── [id].vue      // 对应 "/user/:id"
│       └── profile.vue   // 对应 "/user/profile"

插件将自动映射成如下路由配置:

[
  { path: '/', component: () => import('./src/pages/index.vue') },
  { path: '/about', component: () => import('./src/pages/about.vue') },
  { path: '/user/:id', component: () => import('./src/pages/user/[id].vue') },
  { path: '/user/profile', component: () => import('./src/pages/user/profile.vue') },
]

现在您只需要将自动生成的路由配置可以直接传递给 vue-routercreateRouter 函数。

import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import { routes } from 'vue-router/auto-routes'
import App from './App.vue'

const router = createRouter({
  history: createWebHistory(),
  routes,
})

createApp(App)
  .use(router)
  .mount('#app')

在上面的代码中,我们引入了 router,它是通过 unplugin-vue-router 自动生成的路由配置。然后,使用 app.use(router) 将它挂载到 Vue 应用中。

四、在 Vue 文件中定义路由数据

unplugin-vue-router 插件允许开发者在 Vue 文件中直接定义或覆盖路由配置,这对于自定义路由行为、添加元数据(meta)、修改路由路径等非常有用。以下是如何在 Vue 组件中定义或修改路由数据的几种方法。

1. 使用 definePage()

definePage()unplugin-vue-router 提供的一个全局可用的宏,可以在页面组件的 <script setup> 中调用,用来修改或扩展页面的路由配置。通过 definePage(),你可以添加或修改路由的路径别名、元数据等。

示例:
<script setup lang="ts">
definePage({
  alias: ['/n/:name'],  // 定义路由的别名
  meta: {
    requiresAuth: true,  // 定义元数据,标记该路由需要认证
  },
})
</script>

<template>
  <!-- 页面内容 -->
</template>

在这个例子中:

  • alias:将当前页面路由配置为 /n/:name,即该页面可以通过 /n/xxx 这样的路径访问。
  • meta:添加了一个 requiresAuth: true 的元数据,表示该路由需要用户认证。

参考:uvr.esm.is/guide/eslin…

注意:
  • definePage() 是一个宏,意味着它的参数会在构建时被提取和移除,因此不能使用变量。
  • 如果你的项目使用 ESLint,你需要将 definePage 声明为全局变量,以避免 ESLint 报错。

2. 使用 <route> 自定义块

<route> 自定义块是一种扩展现有路由的方式,它允许你在 .vue 文件中进一步修改或扩展路由配置。你可以通过 <route> 块覆盖路由的名称、路径、元数据等信息。

示例:
<route lang="json">
{
  "name": "name-override",  // 覆盖路由的名称
  "meta": {
    "requiresAuth": false  // 修改路由的元数据,设置不需要
  • name:覆盖默认的路由名称(如果不指定,路由名称会根据文件路径自动生成)。
  • meta:你可以修改或添加路由的元数据。在这个例子中,设置 requiresAuth: false,表示该路由不需要认证。
  • 默认情况下,<route> 块使用 JSON5 格式(比标准 JSON 格式更灵活),但是也支持使用 YAMLJSON 格式。
示例(使用 YAML):
<route lang="yaml">
name: "name-override"
meta:
  requiresAuth: false
</route>

备注:如果你希望使用 YAML 或 JSON 格式,只需要在 <route> 块中指定相应的 lang 属性。

3. 注意事项

  • definePage() 宏会在构建时提取并移除,无法在其中使用变量。
  • definePage()<route> 块主要用于在 Vue 单文件组件(SFC)中直接定义或修改路由配置。
  • 所有的路由配置都会被插件识别,并在生成的 typed-router.d.ts 文件中反映出来,这对于 TypeScript 项目尤其重要。

五、使用 vite-plugin-vue-layouts 提升开发体验

vite-plugin-vue-layouts 是一个非常实用的插件,特别适合与 unplugin-vue-router 配合使用。它让你能够在 Vue 应用中轻松管理布局,使得不同的页面可以使用不同的布局组件,从而提升代码的可维护性和开发效率。

1. 安装 vite-plugin-vue-layouts

首先,确保你已经安装了 vite-plugin-vue-layouts 插件。你可以通过以下命令来安装:

# 使用 npm
npm install vite-plugin-vue-layouts --save-dev

# 使用 yarn
yarn add vite-plugin-vue-layouts --dev

# 使用 pnpm
pnpm add vite-plugin-vue-layouts --dev

2. 配置 vite-plugin-vue-layouts

安装完成后,你需要在 vite.config.ts 中进行配置,确保插件正确启用:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ViteVueLayouts from 'vite-plugin-vue-layouts'
import VueRouter from 'unplugin-vue-router/vite'

export default defineConfig({
  plugins: [
    vue(),
    VueRouter(),
    ViteVueLayouts(),  // 启用 vite-plugin-vue-layouts 插件
  ],
})

然后把自动生成的 layout 配置到路由中:

import { createRouter } from 'vue-router'
import { routes } from 'vue-router/auto-routes'
import { setupLayouts } from 'virtual:generated-layouts'

const router = createRouter({
  // ...
  routes: setupLayouts(routes),
})

同样的,在 tsconfig.json 中声明类型:

{
  "compilerOptions": {
    "types": ["vite-plugin-vue-layouts/client"]
  }
}

3. 目录结构和布局配置

vite-plugin-vue-layouts 插件通过扫描 src/layouts 目录来自动识别和生成布局组件。这使得你可以通过简单的文件命名来实现页面布局的管理。

假设你的项目目录结构如下:

src/
├── layouts/
│   ├── default.vue         // 默认布局
│   └── admin.vue           // 管理员页面布局
├── pages/
│   ├── index.vue           // 使用默认布局的首页
│   ├── about.vue           // 使用默认布局的关于页面
│   └── admin/
│       └── dashboard.vue   // 使用 admin 布局的管理员面板

4. 在页面中使用布局

你可以在页面组件中通过 definePage()<route> 块来指定页面使用的布局。通过这种方式,你可以灵活地为每个页面指定不同的布局。

使用 definePage() 宏来指定布局

src/pages/index.vue 页面中,你可以通过 definePage() 宏指定使用默认布局:

<script setup lang="ts">
definePage({
  layout: 'default',  // 使用 default 布局
})
</script>

<template>
  <h1>Welcome to the Home Page</h1>
</template>

src/pages/admin/dashboard.vue 页面中,你可以指定使用 admin 布局:

<script setup lang="ts">
definePage({
  layout: 'admin',  // 使用 admin 布局
})
</script>

<template>
  <h1>Admin Dashboard</h1>
</template>
使用 <route> 自定义块指定布局

如果你希望使用 <route> 自定义块来配置布局,可以像这样操作:

<route lang="json">
{
  "meta":{
      "layout": "default"
   }
}
</route>

<template>
  <h1>About Page</h1>
</template>

5. 布局文件的编写

vite-plugin-vue-layouts 插件会自动扫描 src/layouts 目录中的布局文件,并将其作为页面的布局组件。你可以根据不同页面的需求,创建不同的布局文件。

例如,创建 default.vue 布局文件:

<!-- src/layouts/default.vue -->
<template>
  <div>
    <header>
      <h1>Header</h1>
    </header>
    <main>
      <RouterView /> <!-- 渲染页面内容 -->
    </main>
    <footer>
      <p>Footer</p>
    </footer>
  </div>
</template>

<script setup lang="ts">
// 可以在这里添加布局相关的逻辑
</script>

创建 admin.vue 布局文件:

<!-- src/layouts/admin.vue -->
<template>
  <div>
    <aside>
      <h2>Admin Sidebar</h2>
    </aside>
    <main>
      <RouterView /> <!-- 渲染页面内容 -->
    </main>
  </div>
</template>

<script setup lang="ts">
// 这里可以加入管理员布局相关的逻辑
</script>

六、总结

在 Vue 项目中,结合使用 unplugin-vue-routervite-plugin-vue-layouts 插件,可以大幅提升开发效率和代码的可维护性。unplugin-vue-router 自动生成路由配置,简化了手动编写路由的工作,而 vite-plugin-vue-layouts 让你轻松管理不同页面的布局。你可以通过 definePage()<route> 块在页面组件中直接指定路由和布局,大大减少了配置的复杂度。此外,vite-plugin-vue-layouts 还支持根据文件夹结构自动匹配布局,提升了项目的灵活性和可扩展性。

我在自己的项目 starter-vite-vue3 中应用了这些插件,实现了自动路由和布局管理,极大简化了开发流程,并提高了项目的可维护性。

参考地址: