2020-12-03 21:49:32 +08:00
import type { AppRouteModule , AppRouteRecordRaw } from '/@/router/types' ;
2021-03-17 00:10:16 +08:00
import type { Router , RouteRecordNormalized } from 'vue-router' ;
2020-12-03 21:49:32 +08:00
import { getParentLayout , LAYOUT } from '/@/router/constant' ;
import { cloneDeep } from 'lodash-es' ;
2021-01-09 23:28:52 +08:00
import { warn } from '/@/utils/log' ;
2021-03-17 00:10:16 +08:00
import { createRouter , createWebHashHistory } from 'vue-router' ;
2020-12-03 21:49:32 +08:00
2020-12-15 14:59:22 +08:00
export type LayoutMapKey = 'LAYOUT' ;
const LayoutMap = new Map < LayoutMapKey , ( ) = > Promise < typeof import ( ' * .vue ' ) > > ( ) ;
2021-03-17 00:10:16 +08:00
let dynamicViewsModules : Record < string , ( ) = > Promise < Recordable > > ;
2021-01-10 20:44:39 +08:00
2021-03-17 00:10:16 +08:00
// Dynamic introduction
2020-12-03 21:49:32 +08:00
function asyncImportRoute ( routes : AppRouteRecordRaw [ ] | undefined ) {
2021-03-02 06:59:38 +08:00
dynamicViewsModules = dynamicViewsModules || import . meta . glob ( '../../views/**/*.{vue,tsx}' ) ;
2020-12-03 21:49:32 +08:00
if ( ! routes ) return ;
routes . forEach ( ( item ) = > {
const { component , name } = item ;
const { children } = item ;
if ( component ) {
2021-01-09 23:28:52 +08:00
item . component = dynamicImport ( dynamicViewsModules , component as string ) ;
2020-12-03 21:49:32 +08:00
} else if ( name ) {
2021-03-17 00:10:16 +08:00
item . component = getParentLayout ( ) ;
2020-12-03 21:49:32 +08:00
}
children && asyncImportRoute ( children ) ;
} ) ;
}
2021-01-10 20:44:39 +08:00
function dynamicImport (
2021-03-17 00:10:16 +08:00
dynamicViewsModules : Record < string , ( ) = > Promise < Recordable > > ,
2021-01-10 20:44:39 +08:00
component : string
) {
const keys = Object . keys ( dynamicViewsModules ) ;
2021-01-09 23:28:52 +08:00
const matchKeys = keys . filter ( ( key ) = > {
2021-03-01 23:01:37 +08:00
let k = key . replace ( '../../views' , '' ) ;
const lastIndex = k . lastIndexOf ( '.' ) ;
k = k . substring ( 0 , lastIndex ) ;
return k === component ;
2021-01-09 23:28:52 +08:00
} ) ;
if ( matchKeys ? . length === 1 ) {
const matchKey = matchKeys [ 0 ] ;
2021-01-10 20:44:39 +08:00
return dynamicViewsModules [ matchKey ] ;
2021-01-09 23:28:52 +08:00
}
if ( matchKeys ? . length > 1 ) {
warn (
'Please do not create `.vue` and `.TSX` files with the same file name in the same hierarchical directory under the views folder. This will cause dynamic introduction failure'
) ;
return ;
}
}
2020-12-03 21:49:32 +08:00
// Turn background objects into routing objects
export function transformObjToRoute < T = AppRouteModule > ( routeList : AppRouteModule [ ] ) : T [ ] {
2020-12-15 14:59:22 +08:00
LayoutMap . set ( 'LAYOUT' , LAYOUT ) ;
2020-12-03 21:49:32 +08:00
routeList . forEach ( ( route ) = > {
if ( route . component ) {
if ( ( route . component as string ) . toUpperCase ( ) === 'LAYOUT' ) {
2021-03-20 16:36:17 +08:00
//route.component = LayoutMap.get(route.component as LayoutMapKey);
route . component = LayoutMap . get ( ( route . component as string ) . toUpperCase ( ) as LayoutMapKey ) ;
2020-12-03 21:49:32 +08:00
} else {
route . children = [ cloneDeep ( route ) ] ;
route . component = LAYOUT ;
route . name = ` ${ route . name } Parent ` ;
route . path = '' ;
const meta = route . meta || { } ;
meta . single = true ;
meta . affix = false ;
route . meta = meta ;
}
}
route . children && asyncImportRoute ( route . children ) ;
} ) ;
return ( routeList as unknown ) as T [ ] ;
}
2021-03-17 00:10:16 +08:00
/ * *
* Convert multi - level routing to level 2 routing
* /
2021-03-23 01:06:32 +08:00
export function flatMultiLevelRoutes ( routeModules : AppRouteModule [ ] ) {
const module s : AppRouteModule [ ] = cloneDeep ( routeModules ) ;
for ( let index = 0 ; index < module s.length ; index ++ ) {
const routeModule = module s [ index ] ;
2021-03-17 00:10:16 +08:00
if ( ! isMultipleRoute ( routeModule ) ) {
continue ;
}
promoteRouteLevel ( routeModule ) ;
}
2021-03-23 01:06:32 +08:00
return module s ;
2021-03-17 00:10:16 +08:00
}
// Routing level upgrade
function promoteRouteLevel ( routeModule : AppRouteModule ) {
// Use vue-router to splice menus
let router : Router | null = createRouter ( {
2021-03-23 01:06:32 +08:00
routes : [ ( routeModule as unknown ) as RouteRecordNormalized ] ,
2021-03-17 00:10:16 +08:00
history : createWebHashHistory ( ) ,
} ) ;
const routes = router . getRoutes ( ) ;
2021-03-23 01:06:32 +08:00
addToChildren ( routes , routeModule . children || [ ] , routeModule ) ;
2021-03-17 00:10:16 +08:00
router = null ;
routeModule . children = routeModule . children ? . filter ( ( item ) = > ! item . children ? . length ) ;
}
// Add all sub-routes to the secondary route
function addToChildren (
routes : RouteRecordNormalized [ ] ,
children : AppRouteRecordRaw [ ] ,
routeModule : AppRouteModule
) {
for ( let index = 0 ; index < children . length ; index ++ ) {
const child = children [ index ] ;
const route = routes . find ( ( item ) = > item . name === child . name ) ;
2021-03-23 01:06:32 +08:00
if ( ! route ) {
continue ;
}
routeModule . children = routeModule . children || [ ] ;
if ( ! routeModule . children . find ( ( item ) = > item . name === route . name ) ) {
routeModule . children ? . push ( ( route as unknown ) as AppRouteModule ) ;
}
if ( child . children ? . length ) {
addToChildren ( routes , child . children , routeModule ) ;
2021-03-17 00:10:16 +08:00
}
}
}
// Determine whether the level exceeds 2 levels
function isMultipleRoute ( routeModule : AppRouteModule ) {
if ( ! routeModule || ! Reflect . has ( routeModule , 'children' ) || ! routeModule . children ? . length ) {
return false ;
}
const children = routeModule . children ;
let flag = false ;
for ( let index = 0 ; index < children . length ; index ++ ) {
const child = children [ index ] ;
if ( child . children ? . length ) {
flag = true ;
break ;
}
}
return flag ;
2020-12-03 21:49:32 +08:00
}