升級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 [email protected] [email protected]
(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