Tag标签

进行标记和分类的小标签。

何时使用

  • 用于标记事物的属性和维度。

  • 进行分类。

代码演示

Tag标签 - 图1

基本

基本标签的用法,可以通过添加 closable 变为可关闭标签。可关闭标签具有 onClose 事件。

  1. import { Tag } from 'antd';
  2. function log(e) {
  3. console.log(e);
  4. }
  5. function preventDefault(e) {
  6. e.preventDefault();
  7. console.log('Clicked! But prevent default.');
  8. }
  9. ReactDOM.render(
  10. <>
  11. <Tag>Tag 1</Tag>
  12. <Tag>
  13. <a href="https://github.com/ant-design/ant-design/issues/1862">Link</a>
  14. </Tag>
  15. <Tag closable onClose={log}>
  16. Tag 2
  17. </Tag>
  18. <Tag closable onClose={preventDefault}>
  19. Prevent Default
  20. </Tag>
  21. </>,
  22. mountNode,
  23. );

Tag标签 - 图2

动态添加和删除

用数组生成一组标签,可以动态添加和删除。

  1. import { Tag, Input, Tooltip } from 'antd';
  2. import { PlusOutlined } from '@ant-design/icons';
  3. class EditableTagGroup extends React.Component {
  4. state = {
  5. tags: ['Unremovable', 'Tag 2', 'Tag 3'],
  6. inputVisible: false,
  7. inputValue: '',
  8. editInputIndex: -1,
  9. editInputValue: '',
  10. };
  11. handleClose = removedTag => {
  12. const tags = this.state.tags.filter(tag => tag !== removedTag);
  13. console.log(tags);
  14. this.setState({ tags });
  15. };
  16. showInput = () => {
  17. this.setState({ inputVisible: true }, () => this.input.focus());
  18. };
  19. handleInputChange = e => {
  20. this.setState({ inputValue: e.target.value });
  21. };
  22. handleInputConfirm = () => {
  23. const { inputValue } = this.state;
  24. let { tags } = this.state;
  25. if (inputValue && tags.indexOf(inputValue) === -1) {
  26. tags = [...tags, inputValue];
  27. }
  28. console.log(tags);
  29. this.setState({
  30. tags,
  31. inputVisible: false,
  32. inputValue: '',
  33. });
  34. };
  35. handleEditInputChange = e => {
  36. this.setState({ editInputValue: e.target.value });
  37. };
  38. handleEditInputConfirm = () => {
  39. this.setState(({ tags, editInputIndex, editInputValue }) => {
  40. const newTags = [...tags];
  41. newTags[editInputIndex] = editInputValue;
  42. return {
  43. tags: newTags,
  44. editInputIndex: -1,
  45. editInputValue: '',
  46. };
  47. });
  48. };
  49. saveInputRef = input => {
  50. this.input = input;
  51. };
  52. saveEditInputRef = input => {
  53. this.editInput = input;
  54. };
  55. render() {
  56. const { tags, inputVisible, inputValue, editInputIndex, editInputValue } = this.state;
  57. return (
  58. <>
  59. {tags.map((tag, index) => {
  60. if (editInputIndex === index) {
  61. return (
  62. <Input
  63. ref={this.saveEditInputRef}
  64. key={tag}
  65. size="small"
  66. className="tag-input"
  67. value={editInputValue}
  68. onChange={this.handleEditInputChange}
  69. onBlur={this.handleEditInputConfirm}
  70. onPressEnter={this.handleEditInputConfirm}
  71. />
  72. );
  73. }
  74. const isLongTag = tag.length > 20;
  75. const tagElem = (
  76. <Tag
  77. className="edit-tag"
  78. key={tag}
  79. closable={index !== 0}
  80. onClose={() => this.handleClose(tag)}
  81. >
  82. <span
  83. onDoubleClick={e => {
  84. if (index !== 0) {
  85. this.setState({ editInputIndex: index, editInputValue: tag }, () => {
  86. this.editInput.focus();
  87. });
  88. e.preventDefault();
  89. }
  90. }}
  91. >
  92. {isLongTag ? `${tag.slice(0, 20)}...` : tag}
  93. </span>
  94. </Tag>
  95. );
  96. return isLongTag ? (
  97. <Tooltip title={tag} key={tag}>
  98. {tagElem}
  99. </Tooltip>
  100. ) : (
  101. tagElem
  102. );
  103. })}
  104. {inputVisible && (
  105. <Input
  106. ref={this.saveInputRef}
  107. type="text"
  108. size="small"
  109. className="tag-input"
  110. value={inputValue}
  111. onChange={this.handleInputChange}
  112. onBlur={this.handleInputConfirm}
  113. onPressEnter={this.handleInputConfirm}
  114. />
  115. )}
  116. {!inputVisible && (
  117. <Tag className="site-tag-plus" onClick={this.showInput}>
  118. <PlusOutlined /> New Tag
  119. </Tag>
  120. )}
  121. </>
  122. );
  123. }
  124. }
  125. ReactDOM.render(<EditableTagGroup />, mountNode);
  1. .site-tag-plus {
  2. background: #fff;
  3. border-style: dashed;
  4. }
  5. .edit-tag {
  6. user-select: none;
  7. }
  8. .tag-input {
  9. width: 78px;
  10. margin-right: 8px;
  11. vertical-align: top;
  12. }

Tag标签 - 图3

控制关闭状态

通过 visible 属性控制关闭状态。

  1. import { Tag, Button } from 'antd';
  2. class Demo extends React.Component {
  3. state = {
  4. visible: true,
  5. };
  6. render() {
  7. return (
  8. <>
  9. <Tag
  10. closable
  11. visible={this.state.visible}
  12. onClose={() => this.setState({ visible: false })}
  13. >
  14. Movies
  15. </Tag>
  16. <br />
  17. <Button size="small" onClick={() => this.setState({ visible: !this.state.visible })}>
  18. Toggle
  19. </Button>
  20. </>
  21. );
  22. }
  23. }
  24. ReactDOM.render(<Demo />, mountNode);

Tag标签 - 图4

图标按钮

当需要在 Tag 内嵌入 Icon 时,可以设置 icon 属性,或者直接在 Tag 内使用 Icon 组件。

如果想控制 Icon 具体的位置,只能直接使用 Icon 组件,而非 icon 属性。

  1. import { Tag } from 'antd';
  2. import {
  3. TwitterOutlined,
  4. YoutubeOutlined,
  5. FacebookOutlined,
  6. LinkedinOutlined,
  7. } from '@ant-design/icons';
  8. ReactDOM.render(
  9. <>
  10. <Tag icon={<TwitterOutlined />} color="#55acee">
  11. Twitter
  12. </Tag>
  13. <Tag icon={<YoutubeOutlined />} color="#cd201f">
  14. Youtube
  15. </Tag>
  16. <Tag icon={<FacebookOutlined />} color="#3b5999">
  17. Facebook
  18. </Tag>
  19. <Tag icon={<LinkedinOutlined />} color="#55acee">
  20. LinkedIn
  21. </Tag>
  22. </>,
  23. mountNode,
  24. );

Tag标签 - 图5

多彩标签

我们添加了多种预设色彩的标签样式,用作不同场景使用。如果预设值不能满足你的需求,可以设置为具体的色值。

  1. import { Tag, Divider } from 'antd';
  2. ReactDOM.render(
  3. <>
  4. <Divider orientation="left">Presets</Divider>
  5. <div>
  6. <Tag color="magenta">magenta</Tag>
  7. <Tag color="red">red</Tag>
  8. <Tag color="volcano">volcano</Tag>
  9. <Tag color="orange">orange</Tag>
  10. <Tag color="gold">gold</Tag>
  11. <Tag color="lime">lime</Tag>
  12. <Tag color="green">green</Tag>
  13. <Tag color="cyan">cyan</Tag>
  14. <Tag color="blue">blue</Tag>
  15. <Tag color="geekblue">geekblue</Tag>
  16. <Tag color="purple">purple</Tag>
  17. </div>
  18. <Divider orientation="left">Custom</Divider>
  19. <div>
  20. <Tag color="#f50">#f50</Tag>
  21. <Tag color="#2db7f5">#2db7f5</Tag>
  22. <Tag color="#87d068">#87d068</Tag>
  23. <Tag color="#108ee9">#108ee9</Tag>
  24. </div>
  25. </>,
  26. mountNode,
  27. );

Tag标签 - 图6

可选择标签

可通过 CheckableTag 实现类似 Checkbox 的效果,点击切换选中效果。

该组件为完全受控组件,不支持非受控用法。

  1. import { Tag } from 'antd';
  2. const { CheckableTag } = Tag;
  3. const tagsData = ['Movies', 'Books', 'Music', 'Sports'];
  4. class HotTags extends React.Component {
  5. state = {
  6. selectedTags: ['Books'],
  7. };
  8. handleChange(tag, checked) {
  9. const { selectedTags } = this.state;
  10. const nextSelectedTags = checked ? [...selectedTags, tag] : selectedTags.filter(t => t !== tag);
  11. console.log('You are interested in: ', nextSelectedTags);
  12. this.setState({ selectedTags: nextSelectedTags });
  13. }
  14. render() {
  15. const { selectedTags } = this.state;
  16. return (
  17. <>
  18. <span style={{ marginRight: 8 }}>Categories:</span>
  19. {tagsData.map(tag => (
  20. <CheckableTag
  21. key={tag}
  22. checked={selectedTags.indexOf(tag) > -1}
  23. onChange={checked => this.handleChange(tag, checked)}
  24. >
  25. {tag}
  26. </CheckableTag>
  27. ))}
  28. </>
  29. );
  30. }
  31. }
  32. ReactDOM.render(<HotTags />, mountNode);

Tag标签 - 图7

添加动画

使用 rc-tween-one 给标签增加添加或删除动画。

  1. import { Tag, Input } from 'antd';
  2. import { TweenOneGroup } from 'rc-tween-one';
  3. import { PlusOutlined } from '@ant-design/icons';
  4. class EditableTagGroup extends React.Component {
  5. state = {
  6. tags: ['Tag 1', 'Tag 2', 'Tag 3'],
  7. inputVisible: false,
  8. inputValue: '',
  9. };
  10. handleClose = removedTag => {
  11. const tags = this.state.tags.filter(tag => tag !== removedTag);
  12. console.log(tags);
  13. this.setState({ tags });
  14. };
  15. showInput = () => {
  16. this.setState({ inputVisible: true }, () => this.input.focus());
  17. };
  18. handleInputChange = e => {
  19. this.setState({ inputValue: e.target.value });
  20. };
  21. handleInputConfirm = () => {
  22. const { inputValue } = this.state;
  23. let { tags } = this.state;
  24. if (inputValue && tags.indexOf(inputValue) === -1) {
  25. tags = [...tags, inputValue];
  26. }
  27. console.log(tags);
  28. this.setState({
  29. tags,
  30. inputVisible: false,
  31. inputValue: '',
  32. });
  33. };
  34. saveInputRef = input => {
  35. this.input = input;
  36. };
  37. forMap = tag => {
  38. const tagElem = (
  39. <Tag
  40. closable
  41. onClose={e => {
  42. e.preventDefault();
  43. this.handleClose(tag);
  44. }}
  45. >
  46. {tag}
  47. </Tag>
  48. );
  49. return (
  50. <span key={tag} style={{ display: 'inline-block' }}>
  51. {tagElem}
  52. </span>
  53. );
  54. };
  55. render() {
  56. const { tags, inputVisible, inputValue } = this.state;
  57. const tagChild = tags.map(this.forMap);
  58. return (
  59. <>
  60. <div style={{ marginBottom: 16 }}>
  61. <TweenOneGroup
  62. enter={{
  63. scale: 0.8,
  64. opacity: 0,
  65. type: 'from',
  66. duration: 100,
  67. onComplete: e => {
  68. e.target.style = '';
  69. },
  70. }}
  71. leave={{ opacity: 0, width: 0, scale: 0, duration: 200 }}
  72. appear={false}
  73. >
  74. {tagChild}
  75. </TweenOneGroup>
  76. </div>
  77. {inputVisible && (
  78. <Input
  79. ref={this.saveInputRef}
  80. type="text"
  81. size="small"
  82. style={{ width: 78 }}
  83. value={inputValue}
  84. onChange={this.handleInputChange}
  85. onBlur={this.handleInputConfirm}
  86. onPressEnter={this.handleInputConfirm}
  87. />
  88. )}
  89. {!inputVisible && (
  90. <Tag onClick={this.showInput} className="site-tag-plus">
  91. <PlusOutlined /> New Tag
  92. </Tag>
  93. )}
  94. </>
  95. );
  96. }
  97. }
  98. ReactDOM.render(<EditableTagGroup />, mountNode);
  1. .site-tag-plus {
  2. background: #fff;
  3. border-style: dashed;
  4. }

Tag标签 - 图8

预设状态的标签

预设五种状态颜色,可以通过设置 colorsuccessprocessingerrordefaultwarning 来代表不同的状态。

  1. import { Tag, Divider } from 'antd';
  2. import {
  3. CheckCircleOutlined,
  4. SyncOutlined,
  5. CloseCircleOutlined,
  6. ExclamationCircleOutlined,
  7. ClockCircleOutlined,
  8. MinusCircleOutlined,
  9. } from '@ant-design/icons';
  10. ReactDOM.render(
  11. <>
  12. <Divider orientation="left">Without icon</Divider>
  13. <div>
  14. <Tag color="success">success</Tag>
  15. <Tag color="processing">processing</Tag>
  16. <Tag color="error">error</Tag>
  17. <Tag color="warning">warning</Tag>
  18. <Tag color="default">default</Tag>
  19. </div>
  20. <Divider orientation="left">With icon</Divider>
  21. <div>
  22. <Tag icon={<CheckCircleOutlined />} color="success">
  23. success
  24. </Tag>
  25. <Tag icon={<SyncOutlined spin />} color="processing">
  26. processing
  27. </Tag>
  28. <Tag icon={<CloseCircleOutlined />} color="error">
  29. error
  30. </Tag>
  31. <Tag icon={<ExclamationCircleOutlined />} color="warning">
  32. warning
  33. </Tag>
  34. <Tag icon={<ClockCircleOutlined />} color="default">
  35. waiting
  36. </Tag>
  37. <Tag icon={<MinusCircleOutlined />} color="default">
  38. stop
  39. </Tag>
  40. </div>
  41. </>,
  42. mountNode,
  43. );

API

Tag

参数说明类型默认值版本
closable标签是否可以关闭(点击默认关闭)booleanfalse
closeIcon自定义关闭按钮ReactNode-4.4.0
color标签色string-
icon设置图标ReactNode-
visible是否显示标签booleantrue
onClose关闭时的回调(可通过 e.preventDefault() 来阻止默认行为)(e) => void-

Tag.CheckableTag

参数说明类型默认值
checked设置标签的选中状态booleanfalse
onChange点击标签时触发的回调(checked) => void-