diff --git a/src/layouts/Layout/index.vue b/src/layouts/Layout/index.vue index 86af8e67..3acf7710 100644 --- a/src/layouts/Layout/index.vue +++ b/src/layouts/Layout/index.vue @@ -1,7 +1,9 @@ diff --git a/src/router/routes/constant.ts b/src/router/routes/constant.ts index b03b2665..d9ff75c3 100644 --- a/src/router/routes/constant.ts +++ b/src/router/routes/constant.ts @@ -1,5 +1,5 @@ import { getLoginModuleRegExp } from '@/utils'; -import type { LoginModuleKey } from '@/interface'; +import { LoginModuleKey } from '@/interface'; /** 固定的路由 */ const constantRoutes: AuthRoute.Route[] = [ @@ -23,7 +23,8 @@ const constantRoutes: AuthRoute.Route[] = [ }, meta: { title: '登录', - single: true + single: true, + singleOriginPath: '/login' } }, { diff --git a/src/styles/css/global.css b/src/styles/css/global.css index f92e90b2..1c332b65 100644 --- a/src/styles/css/global.css +++ b/src/styles/css/global.css @@ -1,4 +1,5 @@ @import './scrollbar.css'; +@import './transition.css'; html, body, #app { height: 100%; diff --git a/src/styles/css/transition.css b/src/styles/css/transition.css new file mode 100644 index 00000000..535d477a --- /dev/null +++ b/src/styles/css/transition.css @@ -0,0 +1,13 @@ +/* fade-slide */ +.fade-slide-leave-active, +.fade-slide-enter-active { + transition: all 0.3s; +} +.fade-slide-enter-from { + opacity: 0; + transform: translateX(-30px); +} +.fade-slide-leave-to { + opacity: 0; + transform: translateX(30px); +} diff --git a/src/typings/common/route.d.ts b/src/typings/common/route.d.ts index 0db524da..40b0d2d0 100644 --- a/src/typings/common/route.d.ts +++ b/src/typings/common/route.d.ts @@ -18,15 +18,11 @@ declare namespace AuthRoute { | 'multi-menu_first_second' | 'about'; - /** 路由Key转换路由Path */ - type KeyToPath = Key extends `${infer Left}_${infer Right}` - ? KeyToPath<`${Left}/${Right}`> - : `/${Key}`; - /** 路由路径 */ type RoutePath = | '/' | Exclude, '/root' | '/redirect'> + | SingleRouteParentPath | Key | '/:path(.*)*' | '/:pathMatch(.*)*'; @@ -61,6 +57,8 @@ declare namespace AuthRoute { hide?: boolean; /** 是否作为单独的路由(作为菜单时只有自身,没有子菜单) */ single?: boolean; + /** 作为单独的路由且path为动态path的原始path */ + singleOriginPath?: SingleRoutePath; /** 路由顺序,可用于菜单的排序 */ order?: number; }; @@ -91,4 +89,27 @@ declare namespace AuthRoute { /** 属性 */ props?: boolean | Record | ((to: any) => Record); } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + type GetMultiRouteParentKey = Key extends `${infer Left}_${infer Right}` ? Left : never; + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + type GetSingleRouteKey = Key extends `${infer Left}_${infer Right}` ? never : Key; + + /** 单独一级路由的key (单独路由需要添加一个父路由用于应用布局组件) */ + type SingleRouteKey = Exclude< + GetSingleRouteKey, + GetMultiRouteParentKey | 'root' | 'redirect-not-found' + >; + + /** 单独路由需要添加一个父路由用于应用布局组件 */ + type SingleRouteParentKey = `${SingleRouteKey}-parent`; + + /** 路由key转换路由path */ + type KeyToPath = Key extends `${infer Left}_${infer Right}` + ? KeyToPath<`${Left}/${Right}`> + : `/${Key}`; + + type SingleRoutePath = KeyToPath; + type SingleRouteParentPath = KeyToPath; } diff --git a/src/utils/router/component.ts b/src/utils/router/component.ts index 5b8fcc1f..3d4b15e4 100644 --- a/src/utils/router/component.ts +++ b/src/utils/router/component.ts @@ -47,7 +47,7 @@ export function getViewComponent(routeKey: AuthRoute.RouteKey) { 'redirect-not-found': NotFound }; - return () => setViewComponentName(viewComponent[key], key); + return () => setViewComponentName(viewComponent[key], key) as Promise; } /** 给页面组件设置名称 */ diff --git a/src/utils/router/helpers.ts b/src/utils/router/helpers.ts index 5645acfd..926402dd 100644 --- a/src/utils/router/helpers.ts +++ b/src/utils/router/helpers.ts @@ -9,11 +9,11 @@ type ComponentAction = { /** 将权限路由类型转换成vue路由类型 */ export function transformAuthRouteToVueRoute(item: AuthRoute.Route) { - const { name, path } = item; + const { name, path, meta } = item; const itemRoute: Partial = { name, path, - meta: item.meta + meta }; if (hasRedirect(item)) { itemRoute.redirect = item.redirect; @@ -41,21 +41,40 @@ export function transformAuthRouteToVueRoute(item: AuthRoute.Route) { } } - if (hasProps(item) && !isSingleRoute(item)) { + if (hasProps(item)) { (itemRoute as any).props = item.props; } if (isSingleRoute(item)) { - itemRoute.children = [ - { - path: '', - name: item.name, - component: getViewComponent(item.name), - props: hasProps(item) ? item.props : undefined - } - ]; - } else if (hasChildren(item)) { - itemRoute.children = item.children!.map(child => transformAuthRouteToVueRoute(child)); + if (item.name === 'redirect-not-found') { + itemRoute.children = [ + { + path: '', + component: getViewComponent('redirect-not-found') + } + ]; + return itemRoute as RouteRecordRaw; + } + const singleRoute = { + ...itemRoute + }; + Object.assign(singleRoute, { component: getViewComponent(item.name) }); + + const singlePath = ( + hasSingleOriginPath(item) ? item.meta.singleOriginPath : item.path + ) as AuthRoute.SingleRoutePath; + const parenPath = `${singlePath}-parent` as AuthRoute.SingleRouteParentPath; + + const parentRoute: Partial = { + path: parenPath, + component: itemRoute.component, + redirect: singlePath, + children: [singleRoute as RouteRecordRaw] + }; + return parentRoute as RouteRecordRaw; + } + if (hasChildren(item)) { + itemRoute.children = item.children!.map(child => transformAuthRouteToVueRoute(child)) as RouteRecordRaw[]; } return itemRoute as RouteRecordRaw; @@ -81,6 +100,10 @@ function isSingleRoute(item: AuthRoute.Route) { return Boolean(item.meta.single); } +function hasSingleOriginPath(item: AuthRoute.Route) { + return Boolean(item.meta.singleOriginPath); +} + /** * 根据路由key获取AuthRoute数据 * @param key - 路由key diff --git a/src/views/system/exception/403.vue b/src/views/system/exception/403.vue index a49ec556..d77f1a3a 100644 --- a/src/views/system/exception/403.vue +++ b/src/views/system/exception/403.vue @@ -1,5 +1,5 @@ diff --git a/src/views/system/exception/500.vue b/src/views/system/exception/500.vue index 37e5be1e..d8396bbf 100644 --- a/src/views/system/exception/500.vue +++ b/src/views/system/exception/500.vue @@ -1,5 +1,5 @@ diff --git a/src/views/system/login/components/PwdLogin/index.vue b/src/views/system/login/components/PwdLogin/index.vue index b91e59f0..e012c37b 100644 --- a/src/views/system/login/components/PwdLogin/index.vue +++ b/src/views/system/login/components/PwdLogin/index.vue @@ -9,7 +9,7 @@
记住我 - 忘记密码? + 忘记密码?

{{ activeModule.label }}

- +