Icon 图标
在3.x版本中,icon的使用方法是:
import { icon } from 'antd';
<icon type="search">
在4.x版本中,修改为:
import { SearchOutlined } from '@ant-design/icons';
<SearchOutLined />
在3.x版本中,button内嵌icon的方法是:
<Button type="primary" icon={search}>
在4.x修改为:
<Button type="primary" icon={<SearchOutlined />}>搜索</Button>
或
<Button type="primary" shape="circle"><SearchOutlined />搜索</Button>
两者的区别在于,后者可以指定icon的位置。
Form 表单
在3.x版本中,form的使用方法是:
import { Form } from 'antd';
const { getFieldDecorator } = form;
// 调用方法
Form.setFieldsValue({...});
return <Form>
<FormItem {...formItemLayout} label="新增成员">
{getFieldDecorator('members',
{
rules: [{ required: true, message: '成员不允许为空' }] ,
initialValue: this.state.name
})(
<Input />,
)
}
</FormItem>
</Form>
在4.x中,修改为:
// 在函数组件中
import { From } from 'antd';
const App = (props) => {
const [formRef] = Form.useForm();
// 调用方法
formRef.setFieldsValue({...})
return
<Form initialValues={{members:this.state.name}} form={formRef}>
<FormItem
{...formItemLayout}
label="新增成员"
name="mumbers"
rules={[{ required: true, message: '成员不允许为空' }]}
>
<Input />
</FormItem>
</Form>
}
或
// 在类组件中
Class Index extends React.Component{
// 按照eslint规则,formRef的声明需要在constructor之前
formRef = Form.useForm();
// 调用方法
formRef.current.setFieldsValue({...})
return
<Form initialValues={{members:this.state.name}} ref={this.formRef}>
<FormItem
{...formItemLayout}
label="新增成员"
name="mumbers"
rules={[{ required: true, message: '成员不允许为空' }]}
>
<Input />
</FormItem>
</Form>
}
FormItem.name表单项名称
一般说来,FormItem的name是这样的:
<Form initialValues={{id: 3}} ref={this.formRef} {...layout}>
<FormItem name="id" label="id">
<Input />
</FormItem>
</Form>
但是,如果有一个对象,格式如下:
info:{
ids:[121, 122];
}
表单项对应的name是info.ids[0]、info.ids[1],那它的写法——
在3.x中:
<Form initialValues={info} ref={this.formRef} {...layout}>
<Form.Item label="id0">
{getFieldDecorator('info.id[0]', {
initialValue:info.ids[0],
})(<Input />)}
</Form.Item>
<Form.Item label="id1">
{getFieldDecorator('info.id[1]', {
initialValue:info.ids[1],
})(<Input />)}
</Form.Item>
</Form>
在4.x中:
<Form initialValues={info} ref={this.formRef} {...layout}>
<FormItem name={["info","ids",0]} label="id0">
<Input />
</FormItem>
<FormItem name={["info","ids",1]} label="id1">
<Input />
</FormItem>
</Form>
3.x和4.x的基本区别:
版本 | 3.x | 4.x |
---|---|---|
创建form | 直接从antd引入 | useForm或createRef |
创建FormItem | getFieldDecorator | 不用 |
初始值initValues | 在创建函数中 | 在Form中 |
校验规则rules | 在创建函数中 | 在FormItem中 |
表单名name | 作为创建函数的第一个参数 | 在FormItem中 |
两种方式构建组件时表单的区别:
构建方式 | 函数 | 类 |
---|---|---|
获取引用 | const formRef = Form.useForm() 其中Form是antd的对象 |
formRef=React.createRef() 必须写在class内部 |
Form属性 | <Form <span style="color:red">form</span>={formRef}></Form> | <Form <span style="color:red">ref</span>={formRef}></Form> |
调用方法 | formRef.getfieldsValue() | formRef.<span style="color:red">current</span>.getfieldsValue() |
校验
在3.x版本中:
validateName = (rule, value, callback) => {
if (!value) return callback('模块名称不能为空!');
this.props.form.setFieldsValue({ name: value.substr(0, 30) });
callback();
}
<FormItem label="模块名称" required {...formItemLayout}>
{getFieldDecorator('name', {
rules: [{ validator: this.validateName }],
})(
<Input />,
)}
</FormItem>
4.x修改为:
validateName = (rule, value) => {
if (!value) return Promise.reject('模块名称不能为空!');
this.props.form.setFieldsValue({ name: value.substr(0, 30) });
Promise.resolve();
}
<FormItem
label="模块名称"
required
{...formItemLayout}
rules=[{ validator: this.validateName }]}
>
<Input />
</FormItem>
主要修改就就是去除了校验函数中的callback,换成了Promise
4.x中的报错:
<div style="color:#ff5858;background-color:#fff0f0;padding:20px">[antd: Form.Item] children
is array of render props cannot have name
.</div>
错误代码:
<FormItem
label="模块名称"
{...formItemLayout}
required
name="name"
rules={[{ validator: this.validateName }]}
>
<Input
placeholder="请输入模块名称"
onBlur={this.onBlur}
onChange={this.onNameChange}
/>
{nameError && <div style={{ color: 'red' }}>{errMsg}</div>}
</FormItem>
出错原因:
在新版本的antd中,要求FormItem有且只能有一个表单元素作为直接子元素,否则除了会报错之外,还会在表单提交时出现无法获取对应的值的问题。
修改:
<FormItem label="模块名称" required {...formItemLayout}>
<FormItem name="name" noStyle rules={[{ validator: this.validateName }]}>
<Input
placeholder="请输入模块名称"
onBlur={this.onBlur}
onChange={this.onNameChange}
/>
</FormItem>
{nameError && <div style={{ color: 'red' }}>{errMsg}</div>}
</FormItem>
其中,为被包裹的FormItem添加noStyle属性以避免其干扰原样式。
请注意各属性的位置。
关于select.filterOption
在3.x :
<Select
filterOptions = {
(input, option) => {
return option.props.children.toLowerCase().indexOf(input.toLowerCase()) > 1;
}
}
>
<Option name="name" value={value} key={key}>
{children}
<Option>
</Select>
在4.x,不再需要props:
<Select
filterOptions = {
(input, option) => {
return option.children.toLowerCase().indexOf(input.toLowerCase()) > 1;
}
}
>
<Option name="name" value={value} key={key}>
{children}
<Option>
</Select>
option/option.children的组成如下:
interface Option{
value: string|number;
key: string|number;
name?: string|number;
children: string
}