用户填写必须的信息以注册新用户。
import {
Form,
Input,
Tooltip,
Icon,
Cascader,
Select,
Row,
Col,
Checkbox,
Button,
AutoComplete,
} from 'antd';
const { Option } = Select;
const AutoCompleteOption = AutoComplete.Option;
const residences = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
];
class RegistrationForm extends React.Component {
state = {
confirmDirty: false,
autoCompleteResult: [],
};
handleSubmit = e => {
e.preventDefault();
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
}
});
};
handleConfirmBlur = e => {
const { value } = e.target;
this.setState({ confirmDirty: this.state.confirmDirty || !!value });
};
compareToFirstPassword = (rule, value, callback) => {
const { form } = this.props;
if (value && value !== form.getFieldValue('password')) {
callback('Two passwords that you enter is inconsistent!');
} else {
callback();
}
};
validateToNextPassword = (rule, value, callback) => {
const { form } = this.props;
if (value && this.state.confirmDirty) {
form.validateFields(['confirm'], { force: true });
}
callback();
};
handleWebsiteChange = value => {
let autoCompleteResult;
if (!value) {
autoCompleteResult = [];
} else {
autoCompleteResult = ['.com', '.org', '.net'].map(domain => `${value}${domain}`);
}
this.setState({ autoCompleteResult });
};
render() {
const { getFieldDecorator } = this.props.form;
const { autoCompleteResult } = this.state;
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 8 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
};
const tailFormItemLayout = {
wrapperCol: {
xs: {
span: 24,
offset: 0,
},
sm: {
span: 16,
offset: 8,
},
},
};
const prefixSelector = getFieldDecorator('prefix', {
initialValue: '86',
})(
<Select style={{ width: 70 }}>
<Option value="86">+86</Option>
<Option value="87">+87</Option>
</Select>,
);
const websiteOptions = autoCompleteResult.map(website => (
<AutoCompleteOption key={website}>{website}</AutoCompleteOption>
));
return (
<Form {...formItemLayout} onSubmit={this.handleSubmit}>
<Form.Item label="E-mail">
{getFieldDecorator('email', {
rules: [
{
type: 'email',
message: 'The input is not valid E-mail!',
},
{
required: true,
message: 'Please input your E-mail!',
},
],
})(<Input />)}
</Form.Item>
<Form.Item label="Password" hasFeedback>
{getFieldDecorator('password', {
rules: [
{
required: true,
message: 'Please input your password!',
},
{
validator: this.validateToNextPassword,
},
],
})(<Input.Password />)}
</Form.Item>
<Form.Item label="Confirm Password" hasFeedback>
{getFieldDecorator('confirm', {
rules: [
{
required: true,
message: 'Please confirm your password!',
},
{
validator: this.compareToFirstPassword,
},
],
})(<Input.Password onBlur={this.handleConfirmBlur} />)}
</Form.Item>
<Form.Item
label={
<span>
Nickname
<Tooltip title="What do you want others to call you?">
<Icon type="question-circle-o" />
</Tooltip>
</span>
}
>
{getFieldDecorator('nickname', {
rules: [{ required: true, message: 'Please input your nickname!', whitespace: true }],
})(<Input />)}
</Form.Item>
<Form.Item label="Habitual Residence">
{getFieldDecorator('residence', {
initialValue: ['zhejiang', 'hangzhou', 'xihu'],
rules: [
{ type: 'array', required: true, message: 'Please select your habitual residence!' },
],
})(<Cascader options={residences} />)}
</Form.Item>
<Form.Item label="Phone Number">
{getFieldDecorator('phone', {
rules: [{ required: true, message: 'Please input your phone number!' }],
})(<Input addonBefore={prefixSelector} style={{ width: '100%' }} />)}
</Form.Item>
<Form.Item label="Website">
{getFieldDecorator('website', {
rules: [{ required: true, message: 'Please input website!' }],
})(
<AutoComplete
dataSource={websiteOptions}
onChange={this.handleWebsiteChange}
placeholder="website"
>
<Input />
</AutoComplete>,
)}
</Form.Item>
<Form.Item label="Captcha" extra="We must make sure that your are a human.">
<Row gutter={8}>
<Col span={12}>
{getFieldDecorator('captcha', {
rules: [{ required: true, message: 'Please input the captcha you got!' }],
})(<Input />)}
</Col>
<Col span={12}>
<Button>Get captcha</Button>
</Col>
</Row>
</Form.Item>
<Form.Item {...tailFormItemLayout}>
{getFieldDecorator('agreement', {
valuePropName: 'checked',
})(
<Checkbox>
I have read the <a href="">agreement</a>
</Checkbox>,
)}
</Form.Item>
<Form.Item {...tailFormItemLayout}>
<Button type="primary" htmlType="submit">
Register
</Button>
</Form.Item>
</Form>
);
}
}
const WrappedRegistrationForm = Form.create({ name: 'register' })(RegistrationForm);
ReactDOM.render(<WrappedRegistrationForm />, mountNode);
<Form.Item label=“Password” hasFeedback> 这里的hasFeedback 是怎么使用的 在输入框的最后显示 √ ×图标,校检使用
hasFeedback | 配合 validateStatus 属性使用,展示校验状态图标,建议只配合 Input 组件使用 | boolean | false |
---|---|---|---|
validator: this.compareToFirstPassword, 这个自定义的参数有什么含义,这是一个有校检作用的一个参数
onBlur 失去焦点事件
JavaScript中的“!!”是什么意思
对于非布尔类型,js会将值先转换成布尔类型,而后取反。
其他类型转布尔型的规则:
字符串类型值,会将空值("")转换成false,其余转换成true。
数字类型,会将0转换成false,其余为true。
null、undefined会转换成false。
因此,对于null、undefined、0、“”都会被转为flase。
说道这里,应该就理解了“!!”的含义了,一个!是将对象转为布尔型并取反,两个!是将取反后的布尔值再取反,相当于直接将非布尔类型值转为布尔类型值。
Input.Password 指输入框出现的小眼睛
参数 | 说明 | 类型 | 默认值 | 版本 |
---|---|---|---|---|
visibilityToggle | 是否显示切换按钮 | boolean | true |
validateFields | 校验并获取一组输入域的值与 Error,若 fieldNames 参数为空,则校验全部组件 |
---|---|
options.force | 对已经校验过的表单域,在 validateTrigger 再次被触发时是否再次校验 |
options.initialValue | 子节点的初始值,类型、可选值均由子节点决定(注意:由于内部校验时使用 === 判断是否变化,建议使用变量缓存所需设置的值而非直接使用字面量) |
---|---|
()
Cascader级联选择
输入框里的值 是由intialValue 定义的初始数组决定 ,对应着级联对象里给的value 值
以label 为主显示
何时使用
- 需要从一组相关联的数据集合进行选择,例如省市区,公司层级,事物分类等。
- 从一个较大的数据集合中进行选择时,用多级分类进行分隔,方便选择。
- 比起 Select 组件,可以在同一个浮层中完成选择,有较好的体验。
addonBefore={prefixSelector}
addonBefore | 带标签的 input,设置前置标签 | string|ReactNode |
---|---|---|
const prefixSelector = getFieldDecorator('prefix', {
initialValue: '86',
})(
<Select style={{ width: 70 }}>
<Option value="86">+86</Option>
<Option value="87">+87</Option>
</Select>,
);
const { Option } = Select;
<AutoComplete
dataSource={websiteOptions}
onChange={this.handleWebsiteChange}
placeholder="website"
\>
<Input />
</AutoComplete>,
AutoComplete自动完成
<Form.Item label="Website">
{getFieldDecorator('website', {
rules: [{ required: true, message: 'Please input website!' }],
})(
<AutoComplete
dataSource={websiteOptions}
onChange={this.handleWebsiteChange}
placeholder="website"
\>
<Input />
</AutoComplete>,
)}
</Form.Item>
基本使用。通过 dataSource 设置自动完成的数据源
onChange | 选中 option,或 input 的 value 变化时,调用此函数 |
---|---|
placeholder | 输入框提示 |
dataSource | 自动完成的数据源 | DataSourceItemType[] |
---|---|---|
const { Option } = Select;
const AutoCompleteOption = AutoComplete.Option;
this.state = {
confirmDirty: false,
autoCompleteResult: [],
const websiteOptions = autoCompleteResult.map(website => (
<AutoCompleteOption key={website}>{website}</AutoCompleteOption>
));
key | 和 value 含义一致。如果 React 需要你设置此项,此项值与 value 的值相同,然后可以省略 value 设置 | string |
---|---|---|
<AutoComplete
dataSource={websiteOptions}
onChange={this.handleWebsiteChange}
placeholder="website"
\>
<Input />
</AutoComplete>,
}
handleWebsiteChange = value => {
let autoCompleteResult;
if (!value) {
autoCompleteResult = [];
} else {
autoCompleteResult = ['.com', '.org', '.net'].map(domain => ${value}${domain});
}
this.setState({ autoCompleteResult });
};
extra | 额外的提示信息,和 help 类似,当需要错误信息和提示文案同时出现时,可以使用这个。 | string|ReactNode |
---|---|---|
options.valuePropName | 子节点的值的属性,如 Switch 的是 ‘checked’ | string | ‘value’ |
---|---|---|---|
labelCol | label 标签布局,同 <Col> 组件,设置 span offset 值,如 {span: 3, offset: 12} 或 sm: {span: 3, offset: 12} 。在 3.14.0 之后,你可以通过 Form 的 labelCol 进行统一设置。当和 Form 同时设置时,以 FormItem 为准。 |
---|---|
wrapperCol | 需要为输入控件设置布局样式时,使用该属性,用法同 labelCol。在 3.14.0 之后,你可以通过 Form 的 wrapperCol 进行统一设置。当和 Form 同时设置时,以 FormItem 为准。 |
---|---|
gutter | 栅格间隔,可以写成像素值或支持响应式的对象写法来设置水平间隔 { xs: 8, sm: 16, md: 24} 。或者使用数组形式同时设置 [水平间距, 垂直间距] (3.24.0 后支持 )。 |
---|---|
内联表单需要用到的一些方法和属性说明
From 属性
参数 | 说明 | 类型 |
---|---|---|
layout | 表单布局 | ‘horizontal’|‘vertical’|‘inline’ |
onSubmit | 数据验证成功后回调事件 | Function(e:Event) |
wrapperCol | (3.14.0 新增,之前的版本只能设置到 FormItem 上。)需要为输入控件设置布局样式时,使用该属性,用法同 labelCol | object |
labelCol | (3.14.0 新增,之前的版本只能设置到 FormItem 上。)label 标签布局,同 <Col> 组件,设置 span offset 值,如 {span: 3, offset: 12} 或 sm: {span: 3, offset: 12} | objecta |
Form.create(options)
class CustomizedForm extends React.Component {}
CustomizedForm = Form.create({})(CustomizedForm);
options
的配置项如下
参数 | 说明 | 类型 |
---|---|---|
name | 设置表单域内字段 id 的前缀 | |
经过 Form.create
包装的组件将会自带 this.props.form
属性注意:使用 getFieldsValue
getFieldValue
setFieldsValue
等时,应确保对应的 field 已经用 getFieldDecorator
注册过了。
getFieldDecorator | 用于和表单进行双向绑定,详见下方描述 | |
---|---|---|
getFieldError | 获取某个输入控件的 Error | Function(name) |
getFieldsError | 获取一组输入控件的 Error ,如不传入参数,则获取全部组件的 Error | Function([names: string[]]) |
validateFields | 校验并获取一组输入域的值与 Error,若 fieldNames 参数为空,则校验全部组件 | ( [fieldNames: string[]], [options: object], callback(errors, values) ) => void |
isFieldTouched | 判断一个输入控件是否经历过 getFieldDecorator 的值收集时机 options.trigger | (name: string) => boolean |
validateFieldsAndScroll | 与 validateFields 相似,但校验完后,如果校验不通过的菜单域不在可见范围内,则自动滚动进可见范围 | 参考 validateFields |
一个 Form.Item 建议只放一个被 getFieldDecorator
装饰过的 child 当有多个被装饰过的 child 时,help
required
validateStatus
无法自动生成。
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
help | 提示信息,如不设置,则会根据校验规则自动生成 | string|ReactNode | |
validateStatus | 校验状态,如不设置,则会根据校验规则自动生成,可选:‘success’ ‘warning’ ‘error’ ‘validating’ | string | |
label | label 标签的文本 | string|ReactNode | |
hasFeedback | 配合 validateStatus 属性使用,展示校验状态图标,建议只配合 Input 组件使用 | boolean | false |
this.props.form.getFieldDecorator(id, options)
经过 getFieldDecorator
包装的控件,表单控件会自动添加 value
(或 valuePropName
指定的其他属性) onChange
(或 trigger
指定的其他属性),数据同步将被 Form 接管,这会导致以下结果:
- 你不再需要也不应该用
onChange
来做同步,但还是可以继续监听onChange
等事件 - 你不能用控件的
value
defaultValue
等属性来设置表单域的值,默认值可以用getFieldDecorator
里的initialValue
。 - 你不应该用
setState
,可以使用this.props.form.setFieldsValue
来动态改变表单值。
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
id | 必填输入控件唯一标志。支持嵌套式的写法。 | string | |
options.rules | 校验规则,参考下方文档 | object[] | |
options.valuePropName | 子节点的值的属性,如 Switch 的是 ‘checked’ | string | ‘value’ |
options.initialValue | 子节点的初始值,类型、可选值均由子节点决定(注意:由于内部校验时使用 === 判断是否变化,建议使用变量缓存所需设置的值而非直接使用字面量) |
校验规则
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
required | 是否必选 | boolean | false |
message | 校验文案 | string|ReactNode | |
type | 内建校验类型,可选项 | string | ‘string’ |
Input
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
type | 声明 input 类型,同原生 input 标签的 type 属性,见:MDN(请直接使用 Input.TextArea 代替 type="textarea" )。 | string | text |
prefix | 带有前缀图标的 input | string|ReactNode | |
placeholder | placeholder 属性提供可描述输入字段预期值的提示信息(hint)。该提示会在输入字段为空时显示,并会在字段获得焦点时消失。 | string | text |
Icon
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
type | 图标类型。遵循图标的命名规范 | string | |
style | 设置图标的样式,例如 fontSize 和 color | CSSProperties | |
<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />
Button
属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
type | 设置按钮类型,可选值为 primary dashed danger link (3.17 中增加) 或者不设 | string | |
htmlType | 设置 button 原生的 type 值,可选值请参考 HTML 标准 | string | button |
disabled | 按钮失效状态 | boolean | false |
Object.keys()
**Object.keys()**方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致 。
Object.keys(obj)
css
css max-width_CSS中的max-width属性
max-width属性用于帮助将元素的宽度设置为最大。 尽管如果元素或内容已经大于最大宽度,则该内容或元素的高度将被更改。
max-width属性不适用于小于最大宽度的内容。 最大宽度属性将覆盖width属性。 max-width属性的默认值为none。 元素的宽度可以用% , px , cm或不测量 。
Element
{
max-width : 50% / 50px /50cm etc.
}