1. 前言

Vue3开发过程中,每次创建新的页面都需要注册路由,需要在src/router.ts中新增页面的路径,并将URL路径映射到组件中,如下所示:

import { createMemoryHistory, createRouter } from 'vue-router'

import HomePageView from './HomePageView.vue'
import DevListView from './DevListView.vue'

const routes = [
  { path: '/', component: HomePageView },
  { path: '/DevListView', component: DevListView },
]

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

虽然看起来工作量不大,但如果页面特别多,就会感到繁琐。即使是微小的改动,如组件名的修改,也需要在路由文件中反复确认,反复如此就会感到不便。为了简化这部分工作,我想到了一个解决方案,那就是开发一个Vue3菜单路由生成工具,只需填写组件的中文名称,根据树形结构生成一个与routes结构相同的数组,然后替换使用即可。但还是觉得不够好,随后想到既然自己能发现这个问题,别人可能早已有了应对方案。接着,我就发现了 unplugin-vue-router 插件。

2. 配置

2.1 安装

npm install -D unplugin-vue-router

2.2 vite.config.ts

import VueRouter from 'unplugin-vue-router/vite'

export default defineConfig({
  plugins: [
    VueRouter({
      /* options */
    }),
    // ⚠️ Vue must be placed after VueRouter()
    Vue(),
  ],
})

2.3 tsconfig.json

{
  "include": [
    // other files...
    "./typed-router.d.ts"
  ],
  "compilerOptions": {
    // ...
    "moduleResolution": "Bundler",
    // ...
  }
}

2.4 vite-env.d.ts

/// <reference types="unplugin-vue-router/client" />

3. 应用

3.1 常规方式

因为项目布局是基于Element Plus组件库的<el-container>搭建的,其中对<e-main>进行了处理,<router-view>是 Vue Router 的一个内置组件,用于渲染匹配当前路由的组件,如下所示:

<el-main>
  <router-view v-slot="{ Component }">
    <component :is="Component" />
  </router-view>
</el-main>

所以,DevList.vueDataList.vue组件都在<e-main>中渲染显示,常规的组件文件结构,如下所示:

src/components/
├── Login.vue
├── Register.vue
├── Container.vue
└── DevManagement
    ├── DevList.vue
    └── DataList.vue

然后,在router.ts文件中是这样的:

import { createRouter, createWebHistory } from 'vue-router';
import Login from '@/components/Login.vue';
import Register from '@/components/Register.vue';
import Container from '@/components/Container.vue';
import DevList from '@/components/DevManagement/DevList.vue';
import DataList from '@/components/DevManagement/DataList.vue';

const routes = [
  {
    path: '/login',
    name: 'Login',
    component: Login
  },
  {
    path: '/register',
    name: 'Register',
    component: Register
  },
  {
    path: '/',
    name: 'Container',
    component: Container,
    children: [
      {
        path: 'DevManagement/DevList',
        name: 'DevList',
        component: DevList
      },
      {
        path: 'DevManagement/DataList',
        name: 'DataList',
        component: DataList
      }
    ]
  }
];
const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
});

export default router;

3.2 使用unplugin-vue-router方式

需将src/components修改为src/pages,然后把登录页Login.vue重命名为index.vue,再创建一个Container文件夹和Container.vue相对应,这样就会自动识别DevList.vueDataList.vueContainer.vue的子路由,其路由为/Container/DevManagement/DevList,如下所示:

src/pages/
├── index.vue
├── Register.vue
├── Container.vue
└── Container
    └── DevManagement
        ├── DevList.vue
        └── DataList.vue

src/router.ts文件中配置如下:

import { createRouter, createWebHashHistory } from 'vue-router'
import { routes, handleHotUpdate } from 'vue-router/auto-routes'

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

// This will update routes at runtime without reloading the page
if (import.meta.hot) { 
  handleHotUpdate(router) 
} 

如此一来,后续只需要在src/pages文件夹下按约定的规范处理即可,不需要在router.ts文件中进行修改了。