refactor(projects): 单独一级路由相关逻辑重构
This commit is contained in:
parent
b93b80cb4b
commit
ab9a6a2f39
@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<div class="h-full">
|
||||
<router-view v-slot="{ Component }">
|
||||
<component :is="Component" />
|
||||
<transition name="fade-slide" mode="out-in" appear>
|
||||
<component :is="Component" />
|
||||
</transition>
|
||||
</router-view>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -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'
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
@import './scrollbar.css';
|
||||
@import './transition.css';
|
||||
|
||||
html, body, #app {
|
||||
height: 100%;
|
||||
|
13
src/styles/css/transition.css
Normal file
13
src/styles/css/transition.css
Normal file
@ -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);
|
||||
}
|
31
src/typings/common/route.d.ts
vendored
31
src/typings/common/route.d.ts
vendored
@ -18,15 +18,11 @@ declare namespace AuthRoute {
|
||||
| 'multi-menu_first_second'
|
||||
| 'about';
|
||||
|
||||
/** 路由Key转换路由Path */
|
||||
type KeyToPath<Key extends string> = Key extends `${infer Left}_${infer Right}`
|
||||
? KeyToPath<`${Left}/${Right}`>
|
||||
: `/${Key}`;
|
||||
|
||||
/** 路由路径 */
|
||||
type RoutePath<Key extends string = '' | LoginPath> =
|
||||
| '/'
|
||||
| Exclude<KeyToPath<RouteKey>, '/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<string, any> | ((to: any) => Record<string, any>);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
type GetMultiRouteParentKey<Key extends string> = Key extends `${infer Left}_${infer Right}` ? Left : never;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
type GetSingleRouteKey<Key extends string> = Key extends `${infer Left}_${infer Right}` ? never : Key;
|
||||
|
||||
/** 单独一级路由的key (单独路由需要添加一个父路由用于应用布局组件) */
|
||||
type SingleRouteKey = Exclude<
|
||||
GetSingleRouteKey<RouteKey>,
|
||||
GetMultiRouteParentKey<RouteKey> | 'root' | 'redirect-not-found'
|
||||
>;
|
||||
|
||||
/** 单独路由需要添加一个父路由用于应用布局组件 */
|
||||
type SingleRouteParentKey = `${SingleRouteKey}-parent`;
|
||||
|
||||
/** 路由key转换路由path */
|
||||
type KeyToPath<Key extends string> = Key extends `${infer Left}_${infer Right}`
|
||||
? KeyToPath<`${Left}/${Right}`>
|
||||
: `/${Key}`;
|
||||
|
||||
type SingleRoutePath = KeyToPath<SingleRouteKey>;
|
||||
type SingleRouteParentPath = KeyToPath<SingleRouteParentKey>;
|
||||
}
|
||||
|
@ -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<Component>;
|
||||
}
|
||||
|
||||
/** 给页面组件设置名称 */
|
||||
|
@ -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<RouteRecordRaw> = {
|
||||
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<RouteRecordRaw> = {
|
||||
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
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div></div>
|
||||
<div>403</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div>NotFound</div>
|
||||
<div>500</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<n-space :vertical="true" :size="24">
|
||||
<div class="flex-y-center justify-between">
|
||||
<n-checkbox v-model:checked="rememberMe">记住我</n-checkbox>
|
||||
<n-button :text="true">忘记密码?</n-button>
|
||||
<n-button :text="true" @click="toLoginModule('reset-pwd')">忘记密码?</n-button>
|
||||
</div>
|
||||
<n-button
|
||||
type="primary"
|
||||
|
@ -16,7 +16,7 @@
|
||||
<main class="pt-24px">
|
||||
<h3 class="text-18px text-primary font-medium">{{ activeModule.label }}</h3>
|
||||
<div class="pt-24px">
|
||||
<transition>
|
||||
<transition name="fade-slide" mode="out-in" appear>
|
||||
<component :is="activeModule.component" />
|
||||
</transition>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user