Input输入框
通过鼠标或键盘输入内容,是最基础的表单域的包装。
何时使用
需要用户输入表单域内容时。
提供组合型输入框,带搜索的输入框,还可以进行大小选择。
代码演示
基本使用。
import { Input } from 'antd';
ReactDOM.render(<Input placeholder="Basic usage" />, mountNode);
用于配置一些固定组合。
import { Input, Select } from 'antd';
import { SettingOutlined } from '@ant-design/icons';
const { Option } = Select;
const selectBefore = (
<Select defaultValue="http://" className="select-before">
<Option value="http://">http://</Option>
<Option value="https://">https://</Option>
</Select>
);
const selectAfter = (
<Select defaultValue=".com" className="select-after">
<Option value=".com">.com</Option>
<Option value=".jp">.jp</Option>
<Option value=".cn">.cn</Option>
<Option value=".org">.org</Option>
</Select>
);
ReactDOM.render(
<>
<div style={{ marginBottom: 16 }}>
<Input addonBefore="http://" addonAfter=".com" defaultValue="mysite" />
</div>
<div style={{ marginBottom: 16 }}>
<Input addonBefore={selectBefore} addonAfter={selectAfter} defaultValue="mysite" />
</div>
<div style={{ marginBottom: 16 }}>
<Input addonAfter={<SettingOutlined />} defaultValue="mysite" />
</div>
<div style={{ marginBottom: 16 }}>
<Input addonBefore="http://" suffix=".com" defaultValue="mysite" />
</div>
</>,
mountNode,
);
.select-before {
width: 90px;
}
.select-after {
width: 80px;
}
[data-theme='compact'] .select-before {
width: 71px;
}
[data-theme='compact'] .select-after {
width: 65px;
}
带有搜索按钮的输入框。
import { Input } from 'antd';
import { AudioOutlined } from '@ant-design/icons';
const { Search } = Input;
const suffix = (
<AudioOutlined
style={{
fontSize: 16,
color: '#1890ff',
}}
/>
);
const onSearch = value => console.log(value);
ReactDOM.render(
<>
<Search placeholder="input search text" onSearch={onSearch} style={{ width: 200 }} />
<Search
placeholder="input search text"
allowClear
onSearch={onSearch}
style={{ width: 200, margin: '0 10px' }}
/>
<br />
<br />
<Search placeholder="input search text" onSearch={onSearch} enterButton />
<br />
<br />
<Search
placeholder="input search text"
allowClear
enterButton="Search"
size="large"
onSearch={onSearch}
/>
<br />
<br />
<Search
placeholder="input search text"
enterButton="Search"
size="large"
suffix={suffix}
onSearch={onSearch}
/>
</>,
mountNode,
);
用于多行输入。
import { Input } from 'antd';
const { TextArea } = Input;
ReactDOM.render(<TextArea rows={4} />, mountNode);
结合 Tooltip 组件,实现一个数值输入框,方便内容超长时的全量展现。
import { Input, Tooltip } from 'antd';
function formatNumber(value) {
value += '';
const list = value.split('.');
const prefix = list[0].charAt(0) === '-' ? '-' : '';
let num = prefix ? list[0].slice(1) : list[0];
let result = '';
while (num.length > 3) {
result = `,${num.slice(-3)}${result}`;
num = num.slice(0, num.length - 3);
}
if (num) {
result = num + result;
}
return `${prefix}${result}${list[1] ? `.${list[1]}` : ''}`;
}
class NumericInput extends React.Component {
onChange = e => {
const { value } = e.target;
const reg = /^-?\d*(\.\d*)?$/;
if ((!isNaN(value) && reg.test(value)) || value === '' || value === '-') {
this.props.onChange(value);
}
};
// '.' at the end or only '-' in the input box.
onBlur = () => {
const { value, onBlur, onChange } = this.props;
let valueTemp = value;
if (value.charAt(value.length - 1) === '.' || value === '-') {
valueTemp = value.slice(0, -1);
}
onChange(valueTemp.replace(/0*(\d+)/, '$1'));
if (onBlur) {
onBlur();
}
};
render() {
const { value } = this.props;
const title = value ? (
<span className="numeric-input-title">{value !== '-' ? formatNumber(value) : '-'}</span>
) : (
'Input a number'
);
return (
<Tooltip
trigger={['focus']}
title={title}
placement="topLeft"
overlayClassName="numeric-input"
>
<Input
{...this.props}
onChange={this.onChange}
onBlur={this.onBlur}
placeholder="Input a number"
maxLength={25}
/>
</Tooltip>
);
}
}
class NumericInputDemo extends React.Component {
constructor(props) {
super(props);
this.state = { value: '' };
}
onChange = value => {
this.setState({ value });
};
render() {
return (
<NumericInput style={{ width: 120 }} value={this.state.value} onChange={this.onChange} />
);
}
}
ReactDOM.render(<NumericInputDemo />, mountNode);
/* to prevent the arrow overflow the popup container,
or the height is not enough when content is empty */
.numeric-input .ant-tooltip-inner {
min-width: 32px;
min-height: 37px;
}
.numeric-input .numeric-input-title {
font-size: 14px;
}
密码框。
import { Input, Space } from 'antd';
import { EyeInvisibleOutlined, EyeTwoTone } from '@ant-design/icons';
ReactDOM.render(
<Space direction="vertical">
<Input.Password placeholder="input password" />
<Input.Password
placeholder="input password"
iconRender={visible => (visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />)}
/>
</Space>,
mountNode,
);
展示字数提示。
import { Input } from 'antd';
const { TextArea } = Input;
ReactDOM.render(<TextArea showCount maxLength={100} />, mountNode);
我们为 <Input />
输入框定义了三种尺寸(大、默认、小),高度分别为 40px
、32px
和 24px
。
import { Input } from 'antd';
import { UserOutlined } from '@ant-design/icons';
ReactDOM.render(
<>
<Input size="large" placeholder="large size" prefix={<UserOutlined />} />
<br />
<br />
<Input placeholder="default size" prefix={<UserOutlined />} />
<br />
<br />
<Input size="small" placeholder="small size" prefix={<UserOutlined />} />
</>,
mountNode,
);
输入框的组合展现。
注意:使用 compact
模式时,不需要通过 Col
来控制宽度。
import { Input, Col, Row, Select, InputNumber, DatePicker, AutoComplete, Cascader } from 'antd';
const { Option } = Select;
const options = [
{
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',
},
],
},
],
},
];
const App = () => (
<div className="site-input-group-wrapper">
<Input.Group size="large">
<Row gutter={8}>
<Col span={5}>
<Input defaultValue="0571" />
</Col>
<Col span={8}>
<Input defaultValue="26888888" />
</Col>
</Row>
</Input.Group>
<br />
<Input.Group compact>
<Input style={{ width: '20%' }} defaultValue="0571" />
<Input style={{ width: '30%' }} defaultValue="26888888" />
</Input.Group>
<br />
<Input.Group compact>
<Select defaultValue="Zhejiang">
<Option value="Zhejiang">Zhejiang</Option>
<Option value="Jiangsu">Jiangsu</Option>
</Select>
<Input style={{ width: '50%' }} defaultValue="Xihu District, Hangzhou" />
</Input.Group>
<br />
<Input.Group compact>
<Input.Search style={{ width: '40%' }} defaultValue="0571" />
<Input.Search allowClear style={{ width: '40%' }} defaultValue="26888888" />
</Input.Group>
<br />
<Input.Group compact>
<Input.Search allowClear style={{ width: '40%' }} defaultValue="0571" />
<Input.Search allowClear style={{ width: '40%' }} defaultValue="26888888" />
</Input.Group>
<br />
<Input.Group compact>
<Select defaultValue="Option1">
<Option value="Option1">Option1</Option>
<Option value="Option2">Option2</Option>
</Select>
<Input style={{ width: '50%' }} defaultValue="input content" />
<InputNumber />
</Input.Group>
<br />
<Input.Group compact>
<Input style={{ width: '50%' }} defaultValue="input content" />
<DatePicker style={{ width: '50%' }} />
</Input.Group>
<br />
<Input.Group compact>
<Input style={{ width: '30%' }} defaultValue="input content" />
<DatePicker.RangePicker style={{ width: '70%' }} />
</Input.Group>
<br />
<Input.Group compact>
<Select defaultValue="Option1-1">
<Option value="Option1-1">Option1-1</Option>
<Option value="Option1-2">Option1-2</Option>
</Select>
<Select defaultValue="Option2-2">
<Option value="Option2-1">Option2-1</Option>
<Option value="Option2-2">Option2-2</Option>
</Select>
</Input.Group>
<br />
<Input.Group compact>
<Select defaultValue="1">
<Option value="1">Between</Option>
<Option value="2">Except</Option>
</Select>
<Input style={{ width: 100, textAlign: 'center' }} placeholder="Minimum" />
<Input
className="site-input-split"
style={{
width: 30,
borderLeft: 0,
borderRight: 0,
pointerEvents: 'none',
}}
placeholder="~"
disabled
/>
<Input
className="site-input-right"
style={{
width: 100,
textAlign: 'center',
}}
placeholder="Maximum"
/>
</Input.Group>
<br />
<Input.Group compact>
<Select defaultValue="Sign Up" style={{ width: '30%' }}>
<Option value="Sign Up">Sign Up</Option>
<Option value="Sign In">Sign In</Option>
</Select>
<AutoComplete
style={{ width: '70%' }}
placeholder="Email"
options={[{ value: 'text 1' }, { value: 'text 2' }]}
/>
</Input.Group>
<br />
<Input.Group compact>
<Select style={{ width: '30%' }} defaultValue="Home">
<Option value="Home">Home</Option>
<Option value="Company">Company</Option>
</Select>
<Cascader style={{ width: '70%' }} options={options} placeholder="Select Address" />
</Input.Group>
</div>
);
ReactDOM.render(<App />, mountNode);
.site-input-group-wrapper .site-input-split {
background-color: #fff;
}
.site-input-group-wrapper .site-input-right {
border-left-width: 0;
}
.site-input-group-wrapper .site-input-right:hover,
.site-input-group-wrapper .site-input-right:focus {
border-left-width: 1px;
}
.site-input-group-wrapper .ant-input-rtl.site-input-right {
border-right-width: 0;
}
.site-input-group-wrapper .ant-input-rtl.site-input-right:hover,
.site-input-group-wrapper .ant-input-rtl.site-input-right:focus {
border-right-width: 1px;
}
用于 onSearch
的时候展示 loading
。
import { Input } from 'antd';
const { Search } = Input;
ReactDOM.render(
<>
<Search placeholder="input search loading default" loading />
<br />
<br />
<Search placeholder="input search loading with enterButton" loading enterButton />
<br />
<br />
<Search placeholder="input search text" enterButton="Search" size="large" loading />
</>,
mountNode,
);
autoSize
属性适用于 textarea
节点,并且只有高度会自动变化。另外 autoSize
可以设定为一个对象,指定最小行数和最大行数。
import { Input } from 'antd';
const { TextArea } = Input;
class Demo extends React.Component {
state = {
value: '',
};
onChange = ({ target: { value } }) => {
this.setState({ value });
};
render() {
const { value } = this.state;
return (
<>
<TextArea placeholder="Autosize height based on content lines" autoSize />
<div style={{ margin: '24px 0' }} />
<TextArea
placeholder="Autosize height with minimum and maximum number of lines"
autoSize={{ minRows: 2, maxRows: 6 }}
/>
<div style={{ margin: '24px 0' }} />
<TextArea
value={value}
onChange={this.onChange}
placeholder="Controlled autosize"
autoSize={{ minRows: 3, maxRows: 5 }}
/>
</>
);
}
}
ReactDOM.render(<Demo />, mountNode);
在输入框上添加前缀或后缀图标。
import { Input, Tooltip } from 'antd';
import { InfoCircleOutlined, UserOutlined } from '@ant-design/icons';
ReactDOM.render(
<>
<Input
placeholder="Enter your username"
prefix={<UserOutlined className="site-form-item-icon" />}
suffix={
<Tooltip title="Extra information">
<InfoCircleOutlined style={{ color: 'rgba(0,0,0,.45)' }} />
</Tooltip>
}
/>
<br />
<br />
<Input prefix="¥" suffix="RMB" />
<br />
<br />
<Input prefix="¥" suffix="RMB" disabled />
</>,
mountNode,
);
带移除图标的输入框,点击图标删除所有内容。
import { Input } from 'antd';
const { TextArea } = Input;
const onChange = e => {
console.log(e);
};
ReactDOM.render(
<>
<Input placeholder="input with clear icon" allowClear onChange={onChange} />
<br />
<br />
<TextArea placeholder="textarea with clear icon" allowClear onChange={onChange} />
</>,
mountNode,
);
没有边框。
import { Input } from 'antd';
ReactDOM.render(<Input placeholder="Borderless" bordered={false} />, mountNode);
API
Input
参数 | 说明 | 类型 | 默认值 | 版本 |
---|---|---|---|---|
addonAfter | 带标签的 input,设置后置标签 | ReactNode | - | |
addonBefore | 带标签的 input,设置前置标签 | ReactNode | - | |
allowClear | 可以点击清除图标删除内容 | boolean | - | |
bordered | 是否有边框 | boolean | true | 4.5.0 |
defaultValue | 输入框默认内容 | string | - | |
disabled | 是否禁用状态,默认为 false | boolean | false | |
id | 输入框的 id | string | - | |
maxLength | 最大长度 | number | - | |
prefix | 带有前缀图标的 input | ReactNode | - | |
size | 控件大小。注:标准表单内的输入框大小限制为 large | large | middle | small | - | |
suffix | 带有后缀图标的 input | ReactNode | - | |
type | 声明 input 类型,同原生 input 标签的 type 属性,见:MDN(请直接使用 Input.TextArea 代替 type=”textarea” ) | string | text | |
value | 输入框内容 | string | - | |
onChange | 输入框内容变化时的回调 | function(e) | - | |
onPressEnter | 按下回车的回调 | function(e) | - |
如果
Input
在Form.Item
内,并且Form.Item
设置了id
和options
属性,则value
defaultValue
和id
属性会被自动设置。
Input 的其他属性和 React 自带的 input 一致。
Input.TextArea
参数 | 说明 | 类型 | 默认值 | 版本 |
---|---|---|---|---|
allowClear | 可以点击清除图标删除内容 | boolean | false | |
autoSize | 自适应内容高度,可设置为 true | false 或对象:{ minRows: 2, maxRows: 6 } | boolean | object | false | |
bordered | 是否有边框 | boolean | true | 4.5.0 |
defaultValue | 输入框默认内容 | string | - | |
maxLength | 内容最大长度 | number | - | 4.7.0 |
showCount | 是否展示字数 | boolean | false | 4.7.0 |
value | 输入框内容 | string | - | |
onPressEnter | 按下回车的回调 | function(e) | - | |
onResize | resize 回调 | function({ width, height }) | - |
Input.TextArea
的其他属性和浏览器自带的 textarea 一致。
Input.Search
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
enterButton | 是否有确认按钮,可设为按钮文字。该属性会与 addonAfter 冲突。 | boolean | ReactNode | false |
loading | 搜索 loading | boolean | false |
onSearch | 点击搜索图标、清除图标,或按下回车键时的回调 | function(value, event) | - |
其余属性和 Input 一致。
Input.Group
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
compact | 是否用紧凑模式 | boolean | false |
size | Input.Group 中所有的 Input 的大小,可选 large default small | string | default |
<Input.Group>
<input />
<input />
</Input.Group>
Input.Password
参数 | 说明 | 类型 | 默认值 | 版本 |
---|---|---|---|---|
iconRender | 自定义切换按钮 | (visible) => ReactNode | (visible) => (visible ? <EyeOutlined /> : <EyeInvisibleOutlined />) | 4.3.0 |
visibilityToggle | 是否显示切换按钮 | boolean | true |
FAQ
为什么我动态改变 prefix/suffix
时,Input 会失去焦点?
当 Input 动态添加或者删除 prefix/suffix
时,React 会重新创建 DOM 结构而新的 input 是没有焦点的。你可以预设一个空的 <span />
来保持 DOM 结构不变:
const suffix = condition ? <Icon type="smile" /> : <span />;
<Input suffix={suffix} />;