Appearance
布局
页面整体布局是一个产品最外层的框架结构,往往会包含导航、侧边栏、面包屑以及内容等。想要了解一个后台项目,先要了解它的基础布局。
UniversalLayout
UniversalLayout 采用的是 Flex 布局,@/layouts/UniversalLayout
目录内容如下:
UniversalLayout # 项目通用 Layout
├── components # UniversalLayout 公共组件
├── css # UniversalLayout 样式目录
├── locales # UniversalLayout 国际化,主要为路由菜单
├── index.tsx # UniversalLayout 入口
└── routes.ts # 使用 UniversalLayout 的页面路由配置
1
2
3
4
5
6
2
3
4
5
6
重要:
如何使用 UniversalLayout
主要在于 UniversalLayout/routes.ts
页面路由配置文件。
配置路由导航
比如:
@/pages/home
页面,想使用UniversalLayout
,你就可以在UniversalLayout/routes.ts
中做出如下配置:
/**
* UniversalLayout 路由配置 入口
* @author LiQingSong
*/
import { lazy } from 'react';
import { IRouter } from '@/@types/router.d';
const universalLayoutRotes: IRouter[] = [
{
path: '/home',
meta: {
icon: 'home',
title: 'universal-layout.menu.home',
},
component: lazy(() => import('@/pages/Home')),
},
];
export default universalLayoutRotes;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
这样你访问 http://localhost:3000/home
就可以看到一个使用了 UniversalLayout
的页面了。
重点:
UniversalLayout/routes.ts
路由配置对应参数说明请查看 路由和菜单
UserLayout
不是所有页面都会用到
UniversalLayout
, 比如登录 、 注册 等页面,所以本项目增加了UserLayout
。
UserLayout
与 UniversalLayout
目录内容基本一致,@/layouts/UserLayout
目录内容如下:
UserLayout # 项目 UserLayout
├── css # UserLayout 样式目录
├── locales # UserLayout 国际化,主要为路由菜单
├── index.tsx # UserLayout 入口
└── routes.ts # 使用 UserLayout 的页面路由配置
1
2
3
4
5
2
3
4
5
重要:
与 UniversalLayout
类似, 如何使用 UserLayout
主要在于 UserLayout/routes.ts
页面路由配置文件。
配置路由导航
比如:登录页[
@/pages/user/login
]、注册页[@/pages/user/register
],想使用UserLayout
,你就可以在UserLayout/routes.ts
中做出如下配置:
import { lazy } from 'react';
import { IRouter } from '@/@types/router';
const pathPre = '/user';
const UserLayoutRoutes: IRouter[] = [
{
path: `${pathPre}/login`,
meta: {
title: 'user-layout.menu.login',
},
component: lazy(() => import('@/pages/user/login')),
},
{
path: `${pathPre}/register`,
meta: {
title: 'user-layout.menu.register',
},
component: lazy(() => import('@/pages/user/register')),
},
];
export default UserLayoutRoutes;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
这样你访问 http://localhost:3000/user/login
、 http://localhost:3000/user/register
就可以看到一个使用了 UserLayout
的登录、注册页面了。
重点:
与 UniversalLayout
一致, UserLayout/routes.ts
路由配置对应参数说明请查看 路由和菜单
自定义Layout
在实际的项目开发中,以上 Layout 并不一定能满足要求,这就需要我们自定义新增 Layout 了。比如我们自定义一个
MemberLayout
,步骤如下:
一、创建目录结构
在目录 @/layouts
下创建 MemberLayout
文件夹,目录如下,
MemberLayout # MemberLayout
├── css # MemberLayout 样式目录
├── locales # MemberLayout 国际化,主要为路由菜单
├── index.tsx # MemberLayout 入口
└── routes.ts # 使用 MemberLayout 的页面路由配置
1
2
3
4
5
2
3
4
5
以上文件对应的代码可以参照 UserLayout
修改和删减。
二、导入框架路由
MemberLayout
创建完成后,需要保证可以路由使用,所以就需要把 MemberLayout/routes.ts
导入 @/config/routes.tsx
中, @/config/routes.tsx
新增如下代码:
/**
* 路由配置 入口
* @author LiQingSong
*/
import React, { lazy, memo, Suspense } from 'react';
import { useLocation, useRoutes } from 'react-router-dom';
import { createUseRoutes, pathKeyCreateUseRoutes } from '@/utils/router';
import PageLoading from '@/components/PageLoading';
// BlankLayout
import BlankLayout from '@/layouts/BlankLayout';
// SecurityLayout
import SecurityLayout from '@/layouts/SecurityLayout';
// UniversalLayout
import UniversalLayoutRoutes from '@/layouts/UniversalLayout/routes';
import UniversalLayout from '@/layouts/UniversalLayout';
// UserLayout
import UserLayoutRoutes from '@/layouts/UserLayout/routes';
import UserLayout from '@/layouts/UserLayout';
// MemberLayout
import MemberLayoutRoutes from '@/layouts/MemberLayout/routes';
import MemberLayout from '@/layouts/MemberLayout';
/**
* 配置所有路由
*/
const routes = createUseRoutes([
{
path: '/',
redirect: '/home',
children: UniversalLayoutRoutes,
},
{
path: '/user',
redirect: '/user/login',
children: UserLayoutRoutes,
},
{
path: '/member',
redirect: '指定跳转需要访问的路由',
children: MemberLayoutRoutes,
},
{
path: '*',
component: lazy(() => import('@/pages/404')),
},
]);
/**
* 配置框架对应的路由
*/
const layoutToRoutes = {
UniversalLayout: pathKeyCreateUseRoutes([routes[0]]),
UserLayout: pathKeyCreateUseRoutes([routes[1]]),
MemberLayout: pathKeyCreateUseRoutes([routes[2]]),
};
export const SuspenseLazy = memo(({ children }: { children: React.ReactNode }) => (
<Suspense fallback={<PageLoading />}>{children}</Suspense>
));
export default memo(() => {
const routesElement = useRoutes(routes);
const location = useLocation();
// 属于 UniversalLayout
if (layoutToRoutes.UniversalLayout[location.pathname]) {
return (
<SecurityLayout>
<UniversalLayout>
<SuspenseLazy>{routesElement}</SuspenseLazy>
</UniversalLayout>
</SecurityLayout>
);
}
// 属于 UserLayout
if (layoutToRoutes.UserLayout[location.pathname]) {
return (
<UserLayout>
<SuspenseLazy>{routesElement}</SuspenseLazy>
</UserLayout>
);
}
// 属于 MemberLayout
if (layoutToRoutes.MemberLayout[location.pathname]) {
return (
<MemberLayout>
<SuspenseLazy>{routesElement}</SuspenseLazy>
</MemberLayout>
);
}
// 默认 BlankLayout
return (
<BlankLayout>
<SuspenseLazy>{routesElement}</SuspenseLazy>
</BlankLayout>
);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
至此新增自定义Layout完成:
使用方法与 UserLayout
、 IndexLayout
一致。