回顾
接上篇,介绍完UMI的环境配置后,我们就要开始着手准备编写一个login页面。简单把这篇文章分成几个模块:
- 改用config配置
- 添加路由管理
- 编写一个login页面
使用config配置的好处
- 统一配置管理:使用config文件可以将所有的配置项集中管理,包括路由配置、代理配置、插件配置等,方便开发者快速查找和修改相关配置。
- 高度可扩展性:umi的config文件支持JavaScript和TypeScript,开发者可以使用编程语言的特性来扩展配置的功能,实现更加灵活的定制化需求。
- 配置文件独立性:将配置项独立成config文件,可以方便地进行版本控制和配置文件的复用,提高项目的可维护性和可扩展性。
- 配置项可覆盖性:umi的config文件支持覆盖配置项,即可以在不同的环境下使用不同的配置,例如开发环境和生产环境可以使用不同的代理配置、路由配置等。
从umi 3.x版本开始,umi的配置文件统一使用config.js或config.ts作为后缀,以提供更好的语法支持和类型检查。使用config.js或config.ts作为配置文件后缀可以让开发者更加方便地使用JavaScript或TypeScript的特性,并且与umi的插件体系更加兼容。因此,推荐使用config.js或config.ts作为umi的配置文件后缀。
编写config.ts
说实话编写config.ts,只是将原本创建umi项目的.umirc.ts的内容,粘贴过去即可。但是稍稍不一样的是咱们还添加了route路由管理,所以,在此,将route路由采用导包的形式即可。
新建config目录,在中添加config.ts和route.ts文件,开始编写代码!
import { defineConfig } from '@umijs/max';
import routes from './routes';
export default defineConfig({
antd: {},
access: {},
model: {},
initialState: {},
request: {},
layout: {
title: '@umijs/max',
},
routes,
npmClient: 'npm',
});
// {
// path: '/welcome',
// component: 'IndexPage',
// name: '欢迎', // 兼容此写法
// icon: 'testicon',
// // 更多功能查看
// // https://beta-pro.ant.design/docs/advanced-menu
// // ---
// // 新页面打开
// target: '_blank',
// // 不展示顶栏
// headerRender: false,
// // 不展示页脚
// footerRender: false,
// // 不展示菜单
// menuRender: false,
// // 不展示菜单顶栏
// menuHeaderRender: false,
// // 权限配置,需要与 plugin-access 插件配合使用
// access: 'canRead',
// // 隐藏子菜单
// hideChildrenInMenu: true,
// // 隐藏自己和子菜单
// hideInMenu: true,
// // 在面包屑中隐藏
// hideInBreadcrumb: true,
// // 子项往上提,仍旧展示,
// flatMenu: true,
// },
export default [
{ path: '/login', layout: false, component: './Login' },
{
path: '/',
redirect: '/home',
},
{
name: '首页',
path: '/home',
component: './Home',
},
{
name: '权限演示',
path: '/access',
component: './Access',
},
{
name: 'CRUD 示例',
path: '/table',
component: './Table',
},
];
至此之后,在pages中添加Login相关内容即可。新建abandon-web/src/pages/Login/index.ts
编写login页面
代码如下:
import {GithubOutlined, LockOutlined, MailOutlined, MobileOutlined, UserOutlined} from '@ant-design/icons';
import {LoginForm, ProFormCheckbox, ProFormText} from '@ant-design/pro-form';
import {message, Tabs} from 'antd';
import React, {useState} from 'react';
const Login: React.FC = () => {
const [type, setType] = useState<string>('account');
console.log(type)
return (
<div style={{
display: 'flex',
flexDirection: 'column',
height: '100vh',
overflow: 'auto',
backgroundImage: "url('https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/V-_oS6r-i7wAAAAAAAAAAAAAFl94AQBr')",
backgroundSize: '100% 100%'
}}>
<div style={{width: 42, height: 42, lineHeight: '42px', position: 'fixed', right: 16, borderRadius: 4}}>
{/* SelectLang组件 */}
</div>
<div style={{flex: '1', padding: '32px 0'}}>
<LoginForm
contentStyle={{minWidth: 280, maxWidth: '75vw'}}
// logo={<img alt="logo" src="/logo.svg" />}
title="Abandon"
subTitle="欢迎来到Abandon"
initialValues={{autoLogin: true}}
>
<Tabs activeKey={type} onChange={setType} centered>
<Tabs.TabPane key="account" tab="登录"/>
<Tabs.TabPane key="register" tab="注册"/>
</Tabs>
{type === 'account' && (
<>
<ProFormText
name="username"
fieldProps={{
size: 'large',
prefix: <UserOutlined/>,
}}
placeholder="Username"
rules={[
{required: true, message: "请输入账号!"},
]}
/>
<ProFormText.Password
name="password"
fieldProps={{
size: 'large',
prefix: <LockOutlined/>,
}}
placeholder="Password"
rules={[
{required: true, message: "请输入密码!"},
]}
/>
</>
)}
{type === 'register' && (
<>
<ProFormText
fieldProps={{
size: 'large',
prefix: <UserOutlined/>,
}}
name="username"
placeholder="请输入用户名"
rules={[
{
required: true,
message: "请输入用户名",
}
]}
/>
<ProFormText
fieldProps={{
size: 'large',
prefix: <MobileOutlined/>,
}}
name="name"
placeholder="请输入姓名"
rules={[
{
required: true,
message: "请输入姓名",
}
]}
/>
<ProFormText
fieldProps={{
size: 'large',
prefix: <MailOutlined/>,
}}
name="email"
placeholder="请输入用户邮箱"
rules={[
{
type: 'email',
required: true,
message: "请输入合法的邮箱",
}
]}
/>
<ProFormText.Password
fieldProps={{
size: 'large',
prefix: <LockOutlined/>,
type: 'password'
}}
name="password"
placeholder="请输入用户密码"
rules={[
{
required: true,
message: "请输入用户密码",
}
]}
/>
</>
)}
<div style={{marginBottom: 24}}>
{type === 'register' ? null :
<ProFormCheckbox noStyle name="autoLogin">记住我</ProFormCheckbox>
}
<a style={{float: 'right'}}>
{type === 'register' ? null :
"忘记密码?"
}
</a>
</div>
</LoginForm>
</div>
{/* Footer组件 */}
</div>
);
};
export default Login;
验证
启动服务,访问http://localhost:9933/login即可看到页面!此页面目前只是包含样式,如账号密码,注册用户等信息,后续跟后端进行联调,发送接口,我们就真正完成了一个前端页面的绘制。当然还有很多不足,都会在一步一步做掉的。样式如下: