2020-12-03 21:49:32 +08:00
import type { AppRouteModule , AppRouteRecordRaw } from '/@/router/types' ;
import type { RouteLocationNormalized , RouteRecordNormalized } from 'vue-router' ;
import { getParentLayout , LAYOUT } from '/@/router/constant' ;
import { cloneDeep } from 'lodash-es' ;
2021-01-09 23:28:52 +08:00
import { warn } from '/@/utils/log' ;
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-01 23:01:37 +08:00
let dynamicViewsModules : Record <
string ,
( ) = > Promise < {
[ key : string ] : any ;
} >
> ;
2021-01-10 20:44:39 +08:00
2020-12-03 21:49:32 +08:00
// 动态引入
function asyncImportRoute ( routes : AppRouteRecordRaw [ ] | undefined ) {
2021-03-01 23:01:37 +08:00
// TODO It may be a bug in Vite. When the conditions are not established, the dynamically imported files will still be packaged in.
if ( ! __DYNAMIC_IMPORT__ ) {
dynamicViewsModules = { } ;
} else {
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 ) {
item . component = getParentLayout ( name ) ;
}
children && asyncImportRoute ( children ) ;
} ) ;
}
2021-01-10 20:44:39 +08:00
function dynamicImport (
dynamicViewsModules : Record <
string ,
( ) = > Promise < {
[ key : string ] : any ;
} >
> ,
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' ) {
2020-12-24 22:02:24 +08:00
route . component = LayoutMap . get ( route . component 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 [ ] ;
}
// Return to the new routing structure, not affected by the original example
export function getRoute ( route : RouteLocationNormalized ) : RouteLocationNormalized {
if ( ! route ) return route ;
const { matched , . . . opt } = route ;
return {
. . . opt ,
matched : ( matched
? matched . map ( ( item ) = > ( {
meta : item.meta ,
name : item.name ,
path : item.path ,
} ) )
: undefined ) as RouteRecordNormalized [ ] ,
} ;
}