Input输入框

通过鼠标或键盘输入内容,是最基础的表单域的包装。

何时使用#

  • 需要用户输入表单域内容时。

  • 提供组合型输入框,带搜索的输入框,还可以进行大小选择。

代码演示

基本使用。

expand codeexpand code
import { Input } from 'antd';
import React from 'react';

const App: React.FC = () => <Input placeholder="Basic usage" />;

export default App;
http://.com
http://
.com
http://.com
cascader

用于配置一些固定组合。

expand codeexpand code
import { SettingOutlined } from '@ant-design/icons';
import { Cascader, Input, Select, Space } from 'antd';
import React from 'react';

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>
);

const App: React.FC = () => (
  <Space direction="vertical">
    <Input addonBefore="http://" addonAfter=".com" defaultValue="mysite" />
    <Input addonBefore={selectBefore} addonAfter={selectAfter} defaultValue="mysite" />
    <Input addonAfter={<SettingOutlined />} defaultValue="mysite" />
    <Input addonBefore="http://" suffix=".com" defaultValue="mysite" />
    <Input
      addonBefore={<Cascader placeholder="cascader" style={{ width: 150 }} />}
      defaultValue="mysite"
    />
  </Space>
);

export default App;
.select-before {
  width: 90px;
}

.select-after {
  width: 80px;
}

[data-theme='compact'] .select-before {
  width: 71px;
}

[data-theme='compact'] .select-after {
  width: 65px;
}
https://

带有搜索按钮的输入框。

expand codeexpand code
import { AudioOutlined } from '@ant-design/icons';
import { Input, Space } from 'antd';
import React from 'react';

const { Search } = Input;

const suffix = (
  <AudioOutlined
    style={{
      fontSize: 16,
      color: '#1890ff',
    }}
  />
);

const onSearch = (value: string) => console.log(value);

const App: React.FC = () => (
  <Space direction="vertical">
    <Search placeholder="input search text" onSearch={onSearch} style={{ width: 200 }} />
    <Search placeholder="input search text" allowClear onSearch={onSearch} style={{ width: 200 }} />
    <Search
      addonBefore="https://"
      placeholder="input search text"
      allowClear
      onSearch={onSearch}
      style={{ width: 304 }}
    />
    <Search placeholder="input search text" onSearch={onSearch} enterButton />
    <Search
      placeholder="input search text"
      allowClear
      enterButton="Search"
      size="large"
      onSearch={onSearch}
    />
    <Search
      placeholder="input search text"
      enterButton="Search"
      size="large"
      suffix={suffix}
      onSearch={onSearch}
    />
  </Space>
);

export default App;


用于多行输入。

expand codeexpand code
import { Input } from 'antd';
import React from 'react';

const { TextArea } = Input;

const App: React.FC = () => (
  <>
    <TextArea rows={4} />
    <br />
    <br />
    <TextArea rows={4} placeholder="maxLength is 6" maxLength={6} />
  </>
);

export default App;

结合 Tooltip 组件,实现一个数值输入框,方便内容超长时的全量展现。

expand codeexpand code
import { Input, Tooltip } from 'antd';
import React, { useState } from 'react';

interface NumericInputProps {
  style: React.CSSProperties;
  value: string;
  onChange: (value: string) => void;
}

const formatNumber = (value: number) => new Intl.NumberFormat().format(value);

const NumericInput = (props: NumericInputProps) => {
  const { value, onChange } = props;

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { value: inputValue } = e.target;
    const reg = /^-?\d*(\.\d*)?$/;
    if (reg.test(inputValue) || inputValue === '' || inputValue === '-') {
      onChange(inputValue);
    }
  };

  // '.' at the end or only '-' in the input box.
  const handleBlur = () => {
    let valueTemp = value;
    if (value.charAt(value.length - 1) === '.' || value === '-') {
      valueTemp = value.slice(0, -1);
    }
    onChange(valueTemp.replace(/0*(\d+)/, '$1'));
  };

  const title = value ? (
    <span className="numeric-input-title">{value !== '-' ? formatNumber(Number(value)) : '-'}</span>
  ) : (
    'Input a number'
  );

  return (
    <Tooltip trigger={['focus']} title={title} placement="topLeft" overlayClassName="numeric-input">
      <Input
        {...props}
        onChange={handleChange}
        onBlur={handleBlur}
        placeholder="Input a number"
        maxLength={16}
      />
    </Tooltip>
  );
};

const App: React.FC = () => {
  const [value, setValue] = useState('');

  return <NumericInput style={{ width: 120 }} value={value} onChange={setValue} />;
};

export default App;
/* 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;
}

密码框。

expand codeexpand code
import { EyeInvisibleOutlined, EyeTwoTone } from '@ant-design/icons';
import { Button, Input, Space } from 'antd';
import React from 'react';

const App: React.FC = () => {
  const [passwordVisible, setPasswordVisible] = React.useState(false);

  return (
    <Space direction="vertical">
      <Input.Password placeholder="input password" allowClear />
      <Input.Password
        allowClear
        placeholder="input password"
        iconRender={visible => (visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />)}
      />
      <Space direction="horizontal">
        <Input.Password
          allowClear
          placeholder="input password"
          visibilityToggle={{ visible: passwordVisible, onVisibleChange: setPasswordVisible }}
        />
        <Button style={{ width: 80 }} onClick={() => setPasswordVisible(prevState => !prevState)}>
          {passwordVisible ? 'Hide' : 'Show'}
        </Button>
      </Space>
    </Space>
  );
};

export default App;
0 / 20

展示字数提示。

expand codeexpand code
import { Input } from 'antd';
import React from 'react';

const { TextArea } = Input;

const onChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
  console.log('Change:', e.target.value);
};

const App: React.FC = () => (
  <>
    <Input showCount maxLength={20} onChange={onChange} />
    <br />
    <br />
    <TextArea showCount maxLength={100} onChange={onChange} />
  </>
);

export default App;

使用 status 为 Input 添加状态,可选 error 或者 warning

expand codeexpand code
import ClockCircleOutlined from '@ant-design/icons/ClockCircleOutlined';
import { Input, Space } from 'antd';
import React from 'react';

const App: React.FC = () => (
  <Space direction="vertical" style={{ width: '100%' }}>
    <Input status="error" placeholder="Error" />
    <Input status="warning" placeholder="Warning" />
    <Input status="error" prefix={<ClockCircleOutlined />} placeholder="Error with prefix" />
    <Input status="warning" prefix={<ClockCircleOutlined />} placeholder="Warning with prefix" />
  </Space>
);

export default App;
4.19.0

聚焦额外配置属性。

expand codeexpand code
import type { InputRef } from 'antd';

import { Button, Input, Space, Switch } from 'antd';
import React, { useRef, useState } from 'react';

const App: React.FC = () => {
  const inputRef = useRef<InputRef>(null);
  const [input, setInput] = useState(true);

  const sharedProps = {
    style: { width: '100%' },
    defaultValue: 'Ant Design love you!',
    ref: inputRef,
  };

  return (
    <Space direction="vertical" style={{ width: '100%' }}>
      <Space wrap>
        <Button
          onClick={() => {
            inputRef.current!.focus({
              cursor: 'start',
            });
          }}
        >
          Focus at first
        </Button>
        <Button
          onClick={() => {
            inputRef.current!.focus({
              cursor: 'end',
            });
          }}
        >
          Focus at last
        </Button>
        <Button
          onClick={() => {
            inputRef.current!.focus({
              cursor: 'all',
            });
          }}
        >
          Focus to select all
        </Button>
        <Button
          onClick={() => {
            inputRef.current!.focus({
              preventScroll: true,
            });
          }}
        >
          Focus prevent scroll
        </Button>
        <Switch
          checked={input}
          checkedChildren="Input"
          unCheckedChildren="TextArea"
          onChange={() => {
            setInput(!input);
          }}
        />
      </Space>
      <br />
      {input ? <Input {...sharedProps} /> : <Input.TextArea {...sharedProps} />}
    </Space>
  );
};

export default App;




我们为 <Input /> 输入框定义了三种尺寸(大、默认、小),高度分别为 40px32px24px

expand codeexpand code
import { UserOutlined } from '@ant-design/icons';
import { Input } from 'antd';
import React from 'react';

const App: React.FC = () => (
  <>
    <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 />} />
  </>
);

export default App;




Zhejiang


Option1



Option1-1
Option2-2

Between

Sign Up

Home
Select Address

输入框的组合展现。

注意:使用 compact 模式时,不需要通过 Col 来控制宽度。

expand codeexpand code
import { CopyOutlined } from '@ant-design/icons';
import {
  AutoComplete,
  Button,
  Cascader,
  Col,
  DatePicker,
  Input,
  InputNumber,
  Row,
  Select,
  Tooltip,
} from 'antd';
import React from 'react';

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: React.FC = () => (
  <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>
      <Input style={{ width: 'calc(100% - 200px)' }} defaultValue="https://ant.design" />
      <Button type="primary">Submit</Button>
    </Input.Group>
    <br />
    <Input.Group compact>
      <Input
        style={{ width: 'calc(100% - 200px)' }}
        defaultValue="git@github.com:ant-design/ant-design.git"
      />
      <Tooltip title="copy git url">
        <Button icon={<CopyOutlined />} />
      </Tooltip>
    </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 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>
);

export default App;
.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

expand codeexpand code
import { Input } from 'antd';
import React from 'react';

const { Search } = Input;

const App: React.FC = () => (
  <>
    <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 />
  </>
);

export default App;

autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象,指定最小行数和最大行数。

expand codeexpand code
import { Input } from 'antd';
import React, { useState } from 'react';

const { TextArea } = Input;

const App: React.FC = () => {
  const [value, setValue] = useState('');

  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={e => setValue(e.target.value)}
        placeholder="Controlled autosize"
        autoSize={{ minRows: 3, maxRows: 5 }}
      />
    </>
  );
};

export default App;


RMB

RMB

在输入框上添加前缀或后缀图标。

expand codeexpand code
import { InfoCircleOutlined, UserOutlined } from '@ant-design/icons';
import { Input, Tooltip } from 'antd';
import React from 'react';

const App: React.FC = () => (
  <>
    <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 />
  </>
);

export default App;


带移除图标的输入框,点击图标删除所有内容。

expand codeexpand code
import { Input } from 'antd';
import React from 'react';

const { TextArea } = Input;

const onChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
  console.log(e);
};

const App: React.FC = () => (
  <>
    <Input placeholder="input with clear icon" allowClear onChange={onChange} />
    <br />
    <br />
    <TextArea placeholder="textarea with clear icon" allowClear onChange={onChange} />
  </>
);

export default App;

展示字数提示。

expand codeexpand code
import { Input } from 'antd';
import React from 'react';

const { TextArea } = Input;

const onChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
  console.log('Change:', e.target.value);
};

const App: React.FC = () => (
  <>
    <TextArea
      showCount
      maxLength={100}
      style={{ height: 120 }}
      onChange={onChange}
      placeholder="can resize"
    />
    <TextArea
      showCount
      maxLength={100}
      style={{ height: 120, resize: 'none' }}
      onChange={onChange}
      placeholder="disable resize"
    />
  </>
);

export default App;

没有边框。

expand codeexpand code
import { Input } from 'antd';
import React from 'react';

const App: React.FC = () => <Input placeholder="Borderless" bordered={false} />;

export default App;

API#

Input#

参数说明类型默认值版本
addonAfter带标签的 input,设置后置标签ReactNode-
addonBefore带标签的 input,设置前置标签ReactNode-
allowClear可以点击清除图标删除内容boolean | { clearIcon: ReactNode }-
bordered是否有边框booleantrue4.5.0
defaultValue输入框默认内容string-
disabled是否禁用状态,默认为 falsebooleanfalse
id输入框的 idstring-
maxLength最大长度number-
showCount是否展示字数boolean | { formatter: (info: { value: string, count: number, maxLength?: number }) => ReactNode }false4.18.0 info.value: 4.23.0
status设置校验状态'error' | 'warning'-4.19.0
prefix带有前缀图标的 inputReactNode-
size控件大小。注:标准表单内的输入框大小限制为 middlelarge | middle | small-
suffix带有后缀图标的 inputReactNode-
type声明 input 类型,同原生 input 标签的 type 属性,见:MDN(请直接使用 Input.TextArea 代替 type="textarea")stringtext
value输入框内容string-
onChange输入框内容变化时的回调function(e)-
onPressEnter按下回车的回调function(e)-

如果 InputForm.Item 内,并且 Form.Item 设置了 idoptions 属性,则 value defaultValueid 属性会被自动设置。

Input 的其他属性和 React 自带的 input 一致。

Input.TextArea#

参数说明类型默认值版本
allowClear可以点击清除图标删除内容booleanfalse
autoSize自适应内容高度,可设置为 true | false 或对象:{ minRows: 2, maxRows: 6 }boolean | objectfalse
bordered是否有边框booleantrue4.5.0
defaultValue输入框默认内容string-
maxLength内容最大长度number-4.7.0
showCount是否展示字数boolean | { formatter: (info: { value: string, count: number, maxLength?: number }) => string }false4.7.0 formatter: 4.10.0 info.value: 4.23.0
value输入框内容string-
onPressEnter按下回车的回调function(e)-
onResizeresize 回调function({ width, height })-

Input.TextArea 的其他属性和浏览器自带的 textarea 一致。

Input.Search#

参数说明类型默认值
enterButton是否有确认按钮,可设为按钮文字。该属性会与 addonAfter 冲突。boolean | ReactNodefalse
loading搜索 loadingbooleanfalse
onSearch点击搜索图标、清除图标,或按下回车键时的回调function(value, event)-

其余属性和 Input 一致。

Input.Group#

参数说明类型默认值
compact是否用紧凑模式booleanfalse
sizeInput.Group 中所有的 Input 的大小,可选 large default smallstringdefault
<Input.Group>
  <input />
  <input />
</Input.Group>

Input.Password#

参数说明类型默认值版本
iconRender自定义切换按钮(visible) => ReactNode(visible) => (visible ? <EyeOutlined /> : <EyeInvisibleOutlined />)4.3.0
visibilityToggle是否显示切换按钮或者控制密码显隐boolean | VisibilityToggletrue

VisibilityToggle#

PropertyDescriptionTypeDefaultVersion
visible用于手动控制密码显隐booleanfalse4.24
onVisibleChange显隐密码的回调boolean-4.24

Input Methods#

名称说明参数版本
blur取消焦点-
focus获取焦点(option?: { preventScroll?: boolean, cursor?: 'start' | 'end' | 'all' })option - 4.10.0

FAQ#

为什么我动态改变 prefix/suffix/showCount 时,Input 会失去焦点?#

当 Input 动态添加或者删除 prefix/suffix/showCount 时,React 会重新创建 DOM 结构而新的 input 是没有焦点的。你可以预设一个空的 <span /> 来保持 DOM 结构不变:

const suffix = condition ? <Icon type="smile" /> : <span />;

<Input suffix={suffix} />;

为何 TextArea 受控时,value 可以超过 maxLength#

受控时,组件应该按照受控内容展示。以防止在表单组件内使用时显示值和提交值不同的问题。

Form表单InputNumber数字输入框