localeCode: zh-CN order: 29 category: 输入类 title: TagInput 标签输入框 icon: doc-tagInput
import { TagInput } from '@douyinfe/semi-ui';
敲击回车键后,输入内容将成为标签。标签内容如果为空串或者纯空格时,则会被过滤。
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
    <TagInput
        defaultValue={['抖音','火山','西瓜视频']}
        placeholder='请输入...'
        onChange={v => console.log(v)}
    />
);
可以使用 separator 设置分隔符,来实现批量输入,它的默认值为英文逗号。1.29.0 版本后支持多个分隔符以 string[] 格式传入。
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
    <>
        <TagInput 
            separator='-' 
            placeholder='使用 - 进行批量输入'
            onChange={v => console.log(v)}
        />
        <br/><br/>
        <TagInput 
            separator={['-', '/', '|', '++']}
            placeholder='支持多个分隔符进行批量输入'
            onChange={v => console.log(v)}
        />
    </>
);
可使用 showClear 设置是否支持一键删除所有标签和输入框内容。
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
    <TagInput 
        showClear 
        defaultValue={['抖音','火山']} 
        placeholder='请输入...'
        onChange={v => console.log(v)}
    />
);
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
    <TagInput 
        disabled 
        showClear 
        defaultValue={['抖音','火山','西瓜视频']} 
        placeholder='请输入...'
    />
);
通过 size 控制标签输入框的大小尺寸,可选: small 、 default 、 large。
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
    <>
        <TagInput size='small' placeholder='small'/>
        <br/><br/>
        <TagInput placeholder='default'/>
        <br/><br/>
        <TagInput size='large' placeholder='large'/>
    </>
);
可以使用 validateStatus 设置不同校验状态的样式,它仅影响背景颜色等样式表现,可选值: default 、 warning 、 error。
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
    <>
        <TagInput placeholder='default'/>
        <br/><br/>
        <TagInput placeholder='warning' validateStatus='warning'/>
        <br/><br/>
        <TagInput placeholder='error' validateStatus='error'/>
    </>
);
可以通过 prefix 传入输入框前缀,通过 suffix 传入输入框后缀,可以为文本或者 ReactNode。
当 prefix、suffix 传入的内容为 string 或者 Icon 时,会自动带上左右间隔;若为自定义 ReactNode,则左右间隔为 0,如需可以在你传入的 ReactNode中自行设置。
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
import { IconVigoLogo, IconGift } from '@douyinfe/semi-icons';
() => (
    <>
        <TagInput prefix={<IconVigoLogo />} />
        <br/><br/>
        <TagInput prefix="Prefix" />
        <br/><br/>
        <TagInput suffix={<IconGift />} />
        <br/><br/>
        <TagInput suffix="Suffix" />
    </>
);
可使用 addOnBlur,设置是否在 blur 事件触发时,将当前 input 的值自动创建成 tag。
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
    <TagInput
        defaultValue={['抖音','火山','西瓜视频']}
        addOnBlur={true}
        placeholder='请输入...'
        onChange={v => console.log(v)}
    />
);
可使用 allowDuplicates,设置是否允许创建相同 tag,默认为 true。
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
    <TagInput
        defaultValue={['抖音','火山','西瓜视频']}
        allowDuplicates={false}
        placeholder='请输入...'
        onChange={v => console.log(v)}
    />
);
可使用 max 限制输入的标签数量,超出后将不允许再输入,并且触发 onExceed() 回调。
可使用 maxLength 限制单个标签的最大长度,超出后将不允许再输入,并且触发 onInputExceed() 回调。
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
    <>
        <TagInput 
            max={3} 
            placeholder='最多输入3条标签..' 
            onChange={v => console.log(v)}
            onExceed={v => {
                Toast.warning('超过 max');
                console.log(v);
            }}
        />
        <TagInput 
            maxLength={5} 
            placeholder='单个标签长度不超过5...'  
            style={{marginTop:12}}
            onChange={v => console.log(v)}
            onInputExceed={v => {
                Toast.warning('超过 maxLength');
                console.log(v);
            }} 
        />
    </>
);
利用 maxTagCount 可以限制展示的标签数量,超出部分将以 +N 的方式展示。使用 showRestTagsPopover 可以设置在超出 maxTagCount 后,hover +N 是否显示 Popover,并且可以在 restTagsPopoverProps 属性中配置 Popover。
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
    <TagInput 
        maxTagCount={2}
        showRestTagsPopover={true}
        restTagsPopoverProps={{ position: 'top' }}
        defaultValue={['抖音','火山','西瓜视频']}
        onChange={v => console.log(v)}
    />
);
可使用 value 设置标签内容,并配合 onChange 实现标签内容受控。
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
class TagInputDemo extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value: ['抖音']
        };
    }
    onChange(value) {
        this.setState({ value });
    }
    
    render() {
        return (
            <TagInput
                value={this.state.value}
                onChange={value => {this.onChange(value);}}
            />
        );
    }
}
可使用 inputValue 设置输入框内容,并配合 onInputChange 实现输入内容受控。
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
class TagInputDemo extends React.Component {
    constructor() {
        super();
        this.state = {
            value: 'abc'
        };
    }
    handleInputChange(value, event) {
        this.setState({ value });
    }
    render() {
        return (
            <TagInput
                inputValue={this.state.value}
                onInputChange={(v,e) => this.handleInputChange(v,e)}
            />
        );
    }
}
import React from 'react';
import { TagInput } from '@douyinfe/semi-ui';
() => (
    <TagInput 
        defaultValue={['抖音']} 
        placeholder='请输入...'
        showClear 
        onFocus={e => {console.log(`onFocus`);}} 
        onBlur={e => {console.log(`onBlur`);}} 
        onChange={tag => {console.log(`onChange,当前标签数组:${tag}`);}} 
        onAdd={tag => {console.log(`onAdd,新增:${tag}`);}} 
        onRemove={(v,i) => {console.log(`onRemove,移除:${v}, 序号:${i}`);}} 
        onInputChange={(input,e) => {console.log(`onInputChange,当前输入内容:${input}`);}} 
    />
);
可以使用 blur() 和 focus() 方法对焦点进行管理。
import React from 'react';
import { TagInput, Button } from '@douyinfe/semi-ui';
class TagInputDemo extends React.Component {
    constructor(props) {
        super(props);
        this.ref = React.createRef();
        this.handleTagInputFocus=this.handleTagInputFocus.bind(this);
    }
    handleTagInputFocus(){
        this.ref.current.focus();
    }
    render() {
        return (
            <>
                <TagInput defaultValue={['抖音','火山']} ref={this.ref} />
                <Button style={{marginTop:10}} onClick={this.handleTagInputFocus}>
                    点击按钮聚焦
                </Button>
            </>
        );
    }
}
可以使用 renderTagItem 自定义标签渲染。
import React from 'react';
import { TagInput, Avatar } from '@douyinfe/semi-ui';
class CustomRender extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value : ['夏可漫']
        };
        this.list = [
            { "name": "夏可漫", "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/avatarDemo.jpeg"},
            { "name": "申悦",  "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bf8647bffab13c38772c9ff94bf91a9d.jpg"},
            { "name": "曲晨一", "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/dbf7351bb779433d17c4f50478cf42f7.jpg"},
            { "name": "文嘉茂", "avatar":  "https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/7abf810ff060ac3387bd027ead92c4e0.jpg"},
        ];
        this.mapList = new Map(this.list.map( item => [item.name,item]));
    }
    renderTagItem(value,index) {
        const data = this.mapList.get(value);
        return (
            <div 
                key={index} 
                style={{display: 'flex', alignItems: 'center', fontSize: 14, marginRight: 10}}
            >
                <Avatar 
                    alt='avatar'
                    src={data?data.avatar:'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/avatarDemo.jpeg'} 
                    size="extra-small" 
                />
                <span style={{ marginLeft: 8 }}>
                    {`${value}@semi.com`}
                </span>
            </div>
        );
    }
    render() {
        const { value } = this.state;
        return (
            <TagInput 
                value={value} 
                onChange={value=>this.setState({value})}
                renderTagItem={(value,index)=>this.renderTagItem(value,index)}
            />
        );
    }
}
| 属性 | 说明 | 类型 | 默认值 | 版本 | 
|---|---|---|---|---|
| addOnBlur | 是否在 blur 事件触发时,将当前 input 的值自动创建成 tag | boolean | false | 1.20.0 | 
| allowDuplicates | 是否允许添加相同 tag | boolean | true | 1.20.0 | 
| autoFocus | 初始渲染时是否自动 focus | boolean | false | 1.29.0 | 
| className | 样式类名 | string | - | 1.19.0 | 
| defaultValue | 初始标签 | string[] | - | 1.19.0 | 
| disabled | 是否禁用 | boolean | false | 1.19.0 | 
| inputValue | 当前输入框,配合 onInputChange 实现受控 | string | - | 1.19.0 | 
| maxLength | 单个标签的最大长度 | number | - | 1.19.0 | 
| max | 允许标签的最大数量 | number | - | 1.21.0 | 
| maxTagCount | 标签的最大展示数量,超出后将以 +N 形式展示 | number | - | 1.21.0 | 
| showRestTagsPopover | 当超过 maxTagCount,hover 到 +N 时,是否通过 Popover 显示剩余内容 | boolean | true | 1.21.0 | 
| restTagsPopoverProps | Popover 的配置属性,可以控制弹出方向、zIndex、trigger等,具体参考Popover | PopoverProps | {} | 1.21.0 | 
| showContentTooltip | 当标签长度过长发生截断时,hover 标签的时候,是否通过 Tooltip 显示全部内容 | boolean | true | 1.21.0 | 
| placeholder | 占位默认值 | string | - | 1.19.0 | 
| prefix | 前缀标签 | ReactNode | - | 1.19.0 | 
| renderTagItem | 自定义标签渲染 | (value: string, index: number) => React.ReactNode | - | 1.19.0 | 
| separator | 设置批量输入时的分隔符 | string|string[] | , | 1.19.0, string[]是从1.29.0开始支持 | 
| showClear | 是否支持一键删除所有标签和输入内容 | boolean | false | 1.19.0 | 
| size | 设置输入框尺寸,可选: small、large、default | 
string | default | 
1.19.0 | 
| style | 内联样式 | React.CSSProperties | - | 1.19.0 | 
| suffix | 后缀标签 | ReactNode | - | 1.19.0 | 
| validateStatus | 设置校验状态样式,可选: default、warning、error | 
string | default | 
1.19.0 | 
| value | 当前标签,配合 onChange 实现受控 | string[] | undefined | - | 1.19.0 | 
| onAdd | 添加标签时的回调 | (addedValue: string[]) => void | - | 1.19.0 | 
| onBlur | 输入框失去焦点时的回调 | (e:React.MouseEvent) => void | - | 1.19.0 | 
| onChange | 标签变化时的回调 | (value:string[]) => void | - | 1.19.0 | 
| onExceed | 超过 max 时的回调 | (value:string[]) => void | - | 1.19.0 | 
| onFocus | 输入框获取焦点时的回调 | (e:React.MouseEvent) => void | - | 1.19.0 | 
| onInputChange | 输入框内容变化时的回调 | (value:string,e: React.KeyboardEvent) => void) | - | 1.19.0 | 
| onInputExceed | 超过 maxLength 时的回调 | (value:string) => void | - | 1.19.0 | 
| onKeyDown | keydown 回调 | (e: React.KeyboardEvent) => void | - | 2.1.0 | 
| onRemove | 移除标签时的回调 | (removedValue: string, idx: number) => void | - | 1.19.0 | 
| 名称 | 描述 | 版本 | 
|---|---|---|
| blur() | 移出焦点 | 1.19.0 | 
| focus() | 获取焦点 | 1.19.0 | 
aria-label 来表示该 TagInput 作用;aria-disabled、aria-invalid;aria-label 来表明元素作用。