vue-plugin-Pages自动配置路由
vite-plugin-pages
使用
安装
首先先安装依赖。因为模版里自带了 vue-router ,所以不需要再安装。
cnpm add vite-plugin-pages vite-plugin-vue-layouts -D
在 vite.config.js 增加以下配置:
import Pages from 'vite-plugin-pages'
export default {
plugins: [
Pages({
dirs: 'src/views', // 需要生成路由的文件目录
exclude: ['**/components/*.vue'] // 排除在外的目录,即不将所有 components 目录下的 .vue 文件生成路由
})
]
}
目前只需要配置这 2 个参数就够了,其它还有更多参数可以去 vite-plugin-pages 项目页了解。
接着在页面中引入就可以使用了。
import { createRouter } from 'vue-router'
import routes from '~pages'
const router = createRouter({
// ...
routes
})
它能够根据pages文件夹下的文件组织结构自动生成一个路由数组,输入到Vue Router 实例中,文件组件结构决定你的路由层级,每次在pages目录下新增一个.vue文件后,即可自动为你创建路由,无需其他配置!
当然 pages 目录可以替换为你任何想要的目录名称,如views。 除了.vue文件,也支持 markdown 等格式在文件。
目前对 react 的支持尚在实验阶段,当然你也可以访问它的主页来了解更多内容。
除此之外,对于常见的路由方式,它也提供了支持:
基础的路由映射
vue-plugin-pages(后称 VPP )会自动将pages目录下的文件映射成相同名字的路由:
- src/pages/users.vue -> /users
- src/pages/users/profile.vue -> /users/profile
- src/pages/settings.vue -> /settings
默认索引路由
以 index 命名的文件会自动当做路由的索引页:
- src/pages/index.vue -> /
- src/pages/users/index.vue -> /users
动态路由
使用方括号来表示动态路由,文件夹和文件都可以动态哦:
- src/pages/users/[id].vue -> /users/:id (/users/one)
- src/[user]/settings.vue -> /:user/settings (/one/settings)
动态参数需要通过 props 传入到目标页面,如 src/pages/users/[id].vue 路由 /users/abc 将需要传递如下参数:
{ "id": "abc" }
嵌套路由
我们可以利用 Vue Router 子路由来创建嵌套布局。可以通过为父组件定义与包含子路由的目录相同的名称来定义父组件。
当我们有如下的目录结构时:
src/pages/
├── users/
│ ├── [id].vue
│ └── index.vue
└── users.vue
将会得到如下的路由配置:
[
{
path: '/users',
component: '/src/pages/users.vue',
children: [
{
path: '',
component: '/src/pages/users/index.vue',
name: 'users'
},
{
path: ':id',
component: '/src/pages/users/[id].vue',
name: 'users-id'
}
]
}
]
捕获所有路由
捕获所有路由使用包含省略号的方括号来表示:
src/pages/[...all].vue -> /* (/non-existent-page)
省略号后的文字将用于命名路由,以及用作传递路由参数的属性名称。
配置及实现
首先使用vite新创建一个vue项目:
# yarn
yarn create @vitejs/app my-vue-app --template vue-ts
cd my-vue-app
yarn add -D vite-plugin-pages
yarn add vue-router@next
然后将以下代码添加到你的vite.config.js中:
import Vue from '@vitejs/plugin-vue';
import Pages from 'vite-plugin-pages';
export default {
plugins: [
Vue(),
Pages()
]
};
修改 main.ts:
import { createApp } from 'vue';
import { createRouter, createWebHistory } from 'vue-router';
import routes from 'virtual:generated-pages';
import App from './App.vue';
console.log(routes);
const router = createRouter({
history: createWebHistory(),
routes,
});
const app = createApp(App);
app.use(router);
app.mount('#app');
修改 App.vue:
<template>
<router-view />
</template>
到此为止已经完成了所有的配置及前置工作,接下来我们在 src 目录下创建 pages 目录,然后按照你的喜好添加文件吧,如:
├── [...all].vue # 捕获所有路由,常用于404
├── about
│ └── index.vue
├── about.vue # 通过/about来访问该页面
├── blog # 通过/blog来访问
│ ├── [id].vue # 动态路由
│ ├── index.vue
│ └── today
├── components.vue
└── index.vue # 当访问本地IP和端口号时的默认页面
如果想要添加其他的文件目录,可以通过修改vite.config.js中的Pages - pagesDir属性进行配置。
vite-plugin-vue-layouts
首先在 vite.config.js 修改下配置:
import Pages from 'vite-plugin-pages'
import Layouts from 'vite-plugin-vue-layouts'
export default {
plugins: [
Pages({
dirs: 'src/views', // 需要生成路由的文件目录
exclude: ['**/components/*.vue'] // 排除在外的目录,即所有 components 目录下的 .vue 文件都不会生成路由
}),
Layouts({
layoutsDirs: 'src/layout', // 布局文件存放目录
defaultLayout: 'index' // 默认布局,对应 src/layout/index.vue
})
]
}
更多配置参数请查看 vite-plugin-vue-layouts 项目页
也还是一样,配置好后,就可以直接使用了。
import { createRouter } from 'vue-router'
import { setupLayouts } from 'virtual:generated-layouts'
import generatedRoutes from 'virtual:generated-pages'
const routes = setupLayouts(generatedRoutes)
const router = createRouter({
// ...
routes
})
这个插件只做一件事,就是把通过 vite-plugin-pages 生成的一级路由处理成嵌套路由,大概就是这样:
// 处理前
{
path: '/login',
component: () => import('/src/views/login.vue'),
name: 'login'
}
// 处理后
{
path: '/login',
component: () => import('/src/layout/index.vue'),
children: [
{
path: '',
component: () => import('/src/views/login.vue'),
name: 'login'
}
]
}
甚至还可以做一些魔改,比如项目中有的路由是需要用到布局页面的,有的则不需要,那我们可以将不需要的页面设置为 layout: false :
<route>
{
meta: {
layout: false
}
}
</route>
同时在路由文件处使用下面这段代码:
import { createRouter } from 'vue-router'
import { setupLayouts } from 'virtual:generated-layouts'
import generatedRoutes from 'virtual:generated-pages'
let routes = []
generatedRoutes.forEach(v => {
routes.push(v?.meta?.layout != false ? setupLayouts([v])[0] : v)
})
const router = createRouter({
// ...
routes
})
总结通过下面这张图配合总结吧:
- 使用路由参数需通过 [ ] 将参数名包裹,并设为文件名
- 文件夹不会生成路由,例如 example 文件夹并没有生成 /example 路由
- 路由 name 会根据文件的目录结构自动生成,并用 - 连接,可确保 name 的唯一性
- 所有 components 目录均不会生成路由