升级antd 4.X
1、andt 4.X
从 antd 3.x 版本升级到 antd 4.x 版本,参考antd官方升级指南[1]。先升级React,然后升级antd,升级命令和发生的错误时的解决方案如下文描述。
1.1. React 16.8升级至17.0.1
(1) 安装React17.0.1:npm install react@17.0.1 react-dom@17.0.1
(2) 执行发生错误时:npm install @babel/runtime
1.2. antd 3.X 升级至4.8.4
安装指令
(1) 安装antd: yarn add antd
(2) 兼容:npx -p @ant-design/codemod-v4 antd4-codemod src
执行发生错误时
执行发生错误时:npm install --save @ant-design/icons
执行发生错误时:npm install --save @ant-design/compatible
安装:yarn add antd yarn add antd
安装:npm install --save react-resizable,后无法编译通过时,重新安装antd,yarn add antd
执行发生错误时:npm start: Browserslist: caniuse-lite is outdated. Please run next command yarn upgrade
: sudo npm i caniuse-lite browserslist,如错误,重新安装antd
2、兼容3.X登录页
import React from 'react';
import { Form } from '@ant-design/compatible';
import { Input, Checkbox, Button } from 'antd';
import { withRouter } from 'react-router-dom';
import { inject, observer } from 'mobx-react';
@withRouter
@inject('HomeStore')
@observer
class LoginPage extends React.Component {
render() {
const { getFieldDecorator } = this.props.form;
return
<Form onSubmit={this.handleSubmit} className="login-form2">
<Form.Item>
{getFieldDecorator('username', {
rules: [{ required: true, message: '请输入您的用户名!' }],
})(
<Input
size="large"
prefix={<i className='iconfont iconuser' style={{ color: '#9D9D9D',marginRight:18,width:24,height:24 }} ></i>}
placeholder="用户名"
style={{ maxWidth: 290,height:50 }}
/>,
)}
</Form.Item>
<Form.Item>
{getFieldDecorator('password', {
rules: [{ required: true, message: '请输入您的密码!' }],
})(
<Input
size="large"
prefix={<i className='iconfont iconpassword' style={{ color: '#9D9D9D',marginRight:18 }}></i>}
type="password"
placeholder="密码"
style={{ maxWidth: 290,height:50 }}
/>,
)}
</Form.Item>
<Form.Item>
{getFieldDecorator('remember', {
valuePropName: 'checked',
initialValue: true,
})(<Checkbox>记住密码</Checkbox>)}
<div className='login-btn2'>
<Button type="primary" style={{ maxWidth: 290,padding:'8px 0', marginTop: 30,fontSize:16 }} htmlType="submit" className="login-form-button2">
登录
</Button>
</div>
</Form.Item>
</Form>
}
handleSubmit = e => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
if (values.remember) {
for (let name in values) {
setCookie(name, values[name]);
}
}
else {
for (let name in values) {
clearCookie(name);
}
}
// 请求登陆接口
this.props.HomeStore.setLogin({
username: values.username,
password: values.password
}, (result) => {
const { success, token, accessToken, refreshToken, tenantId } = result;
if (success) {
sessionStorage.setItem('selfToken', token);
sessionStorage.setItem('accessToken', accessToken);
sessionStorage.setItem('refreshToken', refreshToken);
sessionStorage.setItem('tenantId', tenantId);
sessionStorage.setItem('username', values.username);
this.props.history.push({
pathname: '/',
state: { username: values.username, password: values.password, selfToken: token }
});
}
})
}
});
};
//
componentDidMount() {
this.props.form.setFieldsValue({ 'username': getCookie('username') || '' });
this.props.form.setFieldsValue({ 'password': getCookie('password') || '' });
this.props.form.setFieldsValue({ 'remember': getCookie('remember') || '' });
}
}
const WrappedLoginForm = Form.create({ name: 'login' })(LoginPage);
export default WrappedLoginForm;
3、类组件(Class component)登录页
import React from 'react';
import '@ant-design/compatible/assets/index.css';
import { Form, Input, Checkbox, Button } from 'antd';
import { withRouter } from 'react-router-dom';
import { inject, observer } from 'mobx-react';
@withRouter
@inject('HomeStore')
@observer
class LoginPage extends React.Component {
formRef = React.createRef();
render() {
return
<Form name="basic"
className="login-form2"
onFinish={this.onFinish}
onFinishFailed={this.onFinishFailed}
ref={this.formRef}
>
<Form.Item
name="username"
rules={[
{
required: true,
message: '请输入您的用户名!'
},
]}
>
<Input
size="large"
prefix={<i className='iconfont iconuser' style={{ color: '#9D9D9D',marginRight:18,width:24,height:24 }} ></i>}
placeholder="用户名1"
style={{ maxWidth: 290,height:50 }}
/>
</Form.Item>
<Form.Item
name="password"
rules={[
{
required: true,
message: '请输入您的密码!'
},
]}
>
<Input
size="large"
prefix={<i className='iconfont iconpassword' style={{ color: '#9D9D9D',marginRight:18 }}></i>}
type="password"
placeholder="密码"
style={{ maxWidth: 290,height:50 }}
/>
</Form.Item>
<Form.Item name="remember" valuePropName="checked" initialValue="true">
<Checkbox>记住密码</Checkbox>
</Form.Item>
<Form.Item>
<div className='login-btn2'>
<Button type="primary"
style={{ maxWidth: 290,padding:'8px 0', marginTop: 30,fontSize:16 }}
htmlType="submit"
className="login-form-button2">
登录
</Button>
</div>
</Form.Item>
</Form>
}
onFinish = (values) => {
console.log('Success:', values);
if (values.remember) {
for (let name in values) {
setCookie(name, values[name]);
}
}
else {
for (let name in values) {
clearCookie(name);
}
}
// 请求登陆接口
this.props.HomeStore.setLogin({
username: values.username,
password: values.password
}, (result) => {
const { success, token, accessToken, refreshToken, tenantId } = result;
if (success) {
sessionStorage.setItem('selfToken', token);
sessionStorage.setItem('accessToken', accessToken);
sessionStorage.setItem('refreshToken', refreshToken);
sessionStorage.setItem('tenantId', tenantId);
sessionStorage.setItem('username', values.username);
this.props.history.push({
pathname: '/',
state: { username: values.username, password: values.password, selfToken: token }
});
}
})
};
onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
componentDidMount() {
this.formRef.current.setFieldsValue({ 'username': getCookie('username') || '' });
this.formRef.current.setFieldsValue({ 'password': getCookie('password') || '' });
this.formRef.current.setFieldsValue({ 'remember': getCookie('remember') || '' });
}
}
export default LoginPage;
4、函数组件(Function component)登录页
import React, { useState, useEffect } from 'react';
import { Form, Input, Checkbox, Button } from 'antd';
import { withRouter } from 'react-router-dom';
import { inject, observer } from 'mobx-react';
const LoginPage = (props) => {
const [form] = Form.useForm();
useEffect(()=>{
console.log("仅仅一次执行:相当于componentDidMount");
form.setFieldsValue({ 'username': getCookie('username') || '' });
form.setFieldsValue({ 'password': getCookie('password') || '' });
form.setFieldsValue({ 'remember': getCookie('remember') || '' });
},[]);
const onFinish = (values) => {
console.log('Success:', values);
if (values.remember) {
for (let name in values) {
setCookie(name, values[name]);
}
}
else {
for (let name in values) {
clearCookie(name);
}
}
props.HomeStore.setLogin({
username: values.username,
password: values.password
}, (result) => {
const { success, token, accessToken, refreshToken, tenantId } = result;
if (success) {
sessionStorage.setItem('selfToken', token);
sessionStorage.setItem('accessToken', accessToken);
sessionStorage.setItem('refreshToken', refreshToken);
sessionStorage.setItem('tenantId', tenantId);
sessionStorage.setItem('username', values.username);
props.history.push({
pathname: '/',
state: { username: values.username, password: values.password, selfToken: token }
});
}
})
};
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
return (
<Form name="basic"
className="login-form2"
onFinish={onFinish}
onFinishFailed={onFinishFailed}
form={form}
>
<Form.Item
name="username"
rules={[
{
required: true,
message: '请输入您的用户名!'
},
]}
>
<Input
size="large"
prefix={<i className='iconfont iconuser' style={{ color: '#9D9D9D',marginRight:18,width:24,height:24 }} ></i>}
placeholder="用户名1"
style={{ maxWidth: 290,height:50 }}
/>
</Form.Item>
<Form.Item
name="password"
rules={[
{
required: true,
message: '请输入您的密码!'
},
]}
>
<Input
size="large"
prefix={<i className='iconfont iconpassword' style={{ color: '#9D9D9D',marginRight:18 }}></i>}
type="password"
placeholder="密码"
style={{ maxWidth: 290,height:50 }}
/>
</Form.Item>
<Form.Item name="remember" valuePropName="checked" initialValue="true">
<Checkbox>记住密码</Checkbox>
</Form.Item>
<Form.Item>
<div className='login-btn2'>
<Button type="primary"
style={{ maxWidth: 290,padding:'8px 0', marginTop: 30,fontSize:16 }}
htmlType="submit"
className="login-form-button2">
登录
</Button>
</div>
</Form.Item>
</Form>
);
}
export default inject('HomeStore')(observer(withRouter(LoginPage)));
参考文献:
[1] 从 v3 到 v4,https://ant.design/docs/react/migration-v4-cn