从2.x 升级到 3.x
依赖升级
开发依赖
// package.json "dependencies"
"@gza/quantex-plugin-theme-dark": "^3.0.0", // 新主题
"@gza/quantex-plugin-theme-white": "^3.0.0", // 新主题
"@gza/quantex-scaffold": "^3.0.0" // 新脚手架
配置升级
quantex-scaffold 3.x 的主题加载方式进行了改变
// config/config.ts
const darkChart = require('@gza/quantex-plugin-theme-dark/chart.js');
const whiteChart = require('@gza/quantex-plugin-theme-white/chart.js');
themeConfig: {
defaultTheme: 'themeDark', // 默认主题id
mainTheme: 'themeDark',
themes: [ // 主题列表
{
name: '深色', // 主题名称
id: 'themeDark', // 主题id 必填
path: '@gza/quantex-plugin-theme-dark', // 主题路径
chartConfig: darkChart, // chart 主题配置路径
},
{
name: '浅色',
id: 'themeWhite',
path: '@gza/quantex-plugin-theme-white',
chartConfig: whiteChart,
},
],
}
语法升级
quantex-scaffold 3.x 依赖 ant-design 4.x, ant-design 4.x 中 Form, Icon 语法都做了一定的更改;
Form
V3 Form
import { Form, Icon, Input, Button } from 'antd';
function hasErrors(fieldsError) {
return Object.keys(fieldsError).some(field => fieldsError[field]);
}
class HorizontalLoginForm extends React.Component {
componentDidMount() {
// To disable submit button at the beginning.
this.props.form.validateFields();
}
handleSubmit = e => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
}
});
};
render() {
const { getFieldDecorator, getFieldsError, getFieldError, isFieldTouched } = this.props.form;
// Only show error after a field is touched.
const usernameError = isFieldTouched('username') && getFieldError('username');
const passwordError = isFieldTouched('password') && getFieldError('password');
return (
<Form layout="inline" onSubmit={this.handleSubmit}>
<Form.Item validateStatus={usernameError ? 'error' : ''} help={usernameError || ''}>
{getFieldDecorator('username', {
rules: [{ required: true, message: 'Please input your username!' }],
})(<Input prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />} placeholder="Username" />)}
</Form.Item>
<Form.Item validateStatus={passwordError ? 'error' : ''} help={passwordError || ''}>
{getFieldDecorator('password', {
rules: [{ required: true, message: 'Please input your Password!' }],
})(
<Input
prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />}
type="password"
placeholder="Password"
/>,
)}
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" disabled={hasErrors(getFieldsError())}>
Log in
</Button>
</Form.Item>
</Form>
);
}
}
const WrappedHorizontalLoginForm = Form.create({ name: 'horizontal_login' })(HorizontalLoginForm);
V4 Form: click to read details
import { Form, Input, Button, Checkbox } from 'antd';
const layout = {
labelCol: { span: 8 },
wrapperCol: { span: 16 },
};
const tailLayout = {
wrapperCol: { offset: 8, span: 16 },
};
const Demo = () => {
const onFinish = (values: any) => {
console.log('Success:', values);
};
const onFinishFailed = (errorInfo: any) => {
console.log('Failed:', errorInfo);
};
return (
<Form
{...layout}
name="basic"
initialValues={{ remember: true }}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
>
<Form.Item label="Username" name="username" rules={[{ required: true, message: 'Please input your username!' }]}>
<Input />
</Form.Item>
<Form.Item label="Password" name="password" rules={[{ required: true, message: 'Please input your password!' }]}>
<Input.Password />
</Form.Item>
<Form.Item {...tailLayout} name="remember" valuePropName="checked">
<Checkbox>Remember me</Checkbox>
</Form.Item>
<Form.Item {...tailLayout}>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
);
};
在函数式组件中使用 Form
import { Form, Input, Button, Select } from 'antd';
...
const Demo = () => {
// 获取form实例
const [form] = Form.useForm();
...
const onReset = () => {
// 清空表单
form.resetFields();
};
const onFinish = (values: any) => {
// onFinish 获取的直接是values
console.log(values);
};
const onFill = () => {
// 设置字段
form.setFieldsValue({
note: 'Hello world!',
gender: 'male',
});
};
return (
// form={form} 传入form实例; onSubmit 改为 onFinish
<Form {...layout} form={form} name="control-hooks" onFinish={onFinish}>
<Form.Item name="note" label="Note" rules={[{ required: true }]}>
<Input />
</Form.Item>
<Form.Item name="gender" label="Gender" rules={[{ required: true }]}>
<Select
placeholder="Select a option and change input text above"
onChange={onGenderChange}
allowClear
>
<Option value="male">male</Option>
<Option value="female">female</Option>
<Option value="other">other</Option>
</Select>
</Form.Item>
<Form.Item
noStyle
shouldUpdate={(prevValues, currentValues) => prevValues.gender !== currentValues.gender}
>
{({ getFieldValue }) =>
getFieldValue('gender') === 'other' ? (
<Form.Item name="customizeGender" label="Customize Gender" rules={[{ required: true }]}>
<Input />
</Form.Item>
) : null
}
</Form.Item>
<Form.Item {...tailLayout}>
<Button type="primary" htmlType="submit">
Submit
</Button>
<Button htmlType="button" onClick={onReset}>
Reset
</Button>
</Form.Item>
</Form>
);
};
在类组件中使用 Form
import { Form, Input, Button, Select } from 'antd';
...
class Demo extends React.Component {
// 创建formRef
// 使用this.formRef.current 获取form 实例
formRef = React.createRef();
...
onFinish = (values) => {
console.log(values);
};
onReset = () => {
this.formRef.current.resetFields();
};
onFill = () => {
this.formRef.current.setFieldsValue({
note: 'Hello world!',
gender: 'male',
});
};
render() {
return (
// 传入 ref
<Form {...layout} ref={this.formRef} name="control-ref" onFinish={this.onFinish}>
<Form.Item
name="note"
label="Note"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item
name="gender"
label="Gender"
rules={[
{
required: true,
},
]}
>
<Select
placeholder="Select a option and change input text above"
onChange={this.onGenderChange}
allowClear
>
<Option value="male">male</Option>
<Option value="female">female</Option>
<Option value="other">other</Option>
</Select>
</Form.Item>
<Form.Item
noStyle
shouldUpdate={(prevValues, currentValues) => prevValues.gender !== currentValues.gender}
>
{({ getFieldValue }) =>
getFieldValue('gender') === 'other' ? (
<Form.Item
name="customizeGender"
label="Customize Gender"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
) : null
}
</Form.Item>
<Form.Item {...tailLayout}>
<Button type="primary" htmlType="submit">
Submit
</Button>
<Button htmlType="button" onClick={this.onReset}>
Reset
</Button>
<Button type="link" htmlType="button" onClick={this.onFill}>
Fill form
</Button>
</Form.Item>
</Form>
);
}
}
Icon
用新的 @ant-design/icons 替换字符串类型的 icon 属性值
import { Button } from 'antd';
// tree-shaking supported
- import { Icon } from 'antd';
+ import { SmileOutlined } from '@ant-design/icons';
const Demo = () => (
<div>
- <Icon type="smile" />
+ <SmileOutlined />
- <Button icon="smile" />
+ <Button icon={<SmileOutlined />} />
</div>
);
modal 中使用 icon
import { Modal } from 'antd';
+ import { AntDesignOutlined } from '@ant-design/icons';
Modal.confirm({
- icon: 'ant-design',
+ icon: <AntDesignOutlined />,
title: 'Do you Want to delete these items?',
content: 'Some descriptions',
onOk() {
console.log('OK');
},
onCancel() {
console.log('Cancel');
},
});