【admin-mini】路由篇 vue3手摸手

186 阅读2分钟

logo-mini.jpg

本专栏为了还在Vue2x的广大同胞提供一点升级3X的借鉴思路

适用人群

  • Vue前端开发者

阅读条件

  • 撸一遍Vue3文档

收获

  • 纯净的Vue3-admin框架

如果你是一名成熟的开发工程师,可以直接访问成品

gitee

github


【admin-mini】路由篇

工具生成的默认路由文件

import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView
    },
    {
      path: '/about',
      name: 'about',
      component: () => import('../views/AboutView.vue')
    }
  ]
})

export default router

拆分文件

随着系统增加,路由配置文件可能会越来越长,把他分成两部分,并加入路由守卫以及NProgress进度提示

  • 路由配置文件 /src/router/routes.js
import HomeView from '../views/HomeView.vue'
export default [
    {
        path: '/',
        name: 'home',
        component: HomeView
    },
    {
        path: '/about',
        name: 'about',
        component: () => import('../views/AboutView.vue')
    }
]
  • 路由逻辑文件/src/router/index.js
import { createRouter, createWebHashHistory } from 'vue-router'
import staticRoutes from './routes'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
NProgress.configure({ showSpinner: false })
const router = createRouter({
  history: createWebHashHistory(import.meta.env.BASE_URL),//改为hash路由
  routes: [
    ...staticRoutes,
    { path: '/login', name: 'login', component: () => import('@/views/login.vue') },//登陆界面
    { path: '/:pathMatch(.*)*', component: () => import('@/views/page-404.vue') }//404界面
  ]
})

//路由守卫中加入NProgress
router.beforeEach((to) => {
  NProgress.start()
})

router.afterEach(() => {
  NProgress.done()
})
export default router

自动路由

日常搬砖中,经常遇到在目录中来回切换文件,配置路由的情况; 基于vite的import.meta.glob,完全可以实现自动化导入

根据日常搬砖的经验;很快就能得到以下需求:

  1. 每个导入的路由可以自定义属性
  2. 可以既能自动导入,也可以手动导入
  3. 可以实现排序,不能只按照文件命名排序吧

先制定以下规则

  1. 使用auto-route.js文件来配置自定义属性(达成需求1)
  2. 一个目录下 存在auto-route.js文件 并且 存在index.vue 那么就自动导入(达成需求2)
  3. 路由配置中 增加一个weight 权重属性,来实现排序(达成需求3)

e.g

  • views
    • user
      • index.vue
      • auto-route.js
    • product
      • index.vue
      • auto-route.js
    • .....

导入index.vue

深度扫描/views/下所有auto-route.js以及index.vue文件

//src/router/route.js
const autoImportPage = import.meta.glob(['@/views/**/index.vue'])
const autoImportPageInfo = import.meta.glob(['@/views/**/auto-route.js'], { eager: true })

处理并生成路由

let autoImportRotesCache = {}
let autoImportRotes = []
for (let path in autoImportPageInfo) {
  let pathList = path.split('/').slice(3, -1)
  let realPath = pathList.join('/')
  let route = {
    name: realPath,
    path: realPath,
    meta: {
      name: realPath
    },
    component: autoImportPage['/src/views/' + realPath + '/index.vue'] || RouterView
  }
  let info = autoImportPageInfo[path]
  if (info) {
    Object.assign(route, info.default)
  }
  autoImportRotesCache[pathList.join('/')] = route
  let parentRoute = autoImportRotesCache[pathList.slice(0, -1).join('/')]
  if (pathList.length > 1 && parentRoute) {
    parentRoute.children = parentRoute.children || []
    parentRoute.children.push(route)
    parentRoute.children.sort((a, b) => {
      return (b.weight || 0) - (a.weight || 0)
    })
  } else {
    autoImportRotes.push(route)
  }
}

合并路由并排序最外层

autoImportRotes.push({
  path: '',
  weight: 100,
  meta: { name: '首页', icon: 'House' },
  component: () => import('@/views/home.vue')
})

autoImportRotes.sort((a, b) => {
  return (b.weight || 0) - (a.weight || 0)
})
export default [
  {
    path: '/',
    component: BaseLayout,
    children: [...autoImportRotes]
  }
]


auto-route.js配置实例:

export default {
  meta: {
    name: 'admin-table',
    icon: 'Grid'
  }
}

恭喜你,完成了自动导入🎉