Mentions提及

提及组件。

原 Mention 组件已废弃,原文档请点击这里

何时使用

用于在输入中提及某人或某事,常用于发布、聊天或评论功能。

代码演示

Mentions提及 - 图1

基本使用

基本使用

  1. import { Mentions } from 'antd';
  2. const { Option } = Mentions;
  3. function onChange(value) {
  4. console.log('Change:', value);
  5. }
  6. function onSelect(option) {
  7. console.log('select', option);
  8. }
  9. ReactDOM.render(
  10. <Mentions
  11. style={{ width: '100%' }}
  12. onChange={onChange}
  13. onSelect={onSelect}
  14. defaultValue="@afc163"
  15. >
  16. <Option value="afc163">afc163</Option>
  17. <Option value="zombieJ">zombieJ</Option>
  18. <Option value="yesmeck">yesmeck</Option>
  19. </Mentions>,
  20. mountNode,
  21. );

Mentions提及 - 图2

配合 Form 使用

受控模式,例如配合 Form 使用。

  1. import { Mentions, Form, Button } from 'antd';
  2. const { Option, getMentions } = Mentions;
  3. class App extends React.Component {
  4. handleReset = e => {
  5. e.preventDefault();
  6. this.props.form.resetFields();
  7. };
  8. handleSubmit = e => {
  9. e.preventDefault();
  10. this.props.form.validateFields((errors, values) => {
  11. if (errors) {
  12. console.log('Errors in the form!!!');
  13. return;
  14. }
  15. console.log('Submit!!!');
  16. console.log(values);
  17. });
  18. };
  19. checkMention = (rule, value, callback) => {
  20. const mentions = getMentions(value);
  21. if (mentions.length < 2) {
  22. callback(new Error('More than one must be selected!'));
  23. } else {
  24. callback();
  25. }
  26. };
  27. render() {
  28. const {
  29. form: { getFieldDecorator },
  30. } = this.props;
  31. return (
  32. <Form layout="horizontal">
  33. <Form.Item label="Top coders" labelCol={{ span: 6 }} wrapperCol={{ span: 16 }}>
  34. {getFieldDecorator('coders', {
  35. rules: [{ validator: this.checkMention }],
  36. })(
  37. <Mentions rows="1">
  38. <Option value="afc163">afc163</Option>
  39. <Option value="zombieJ">zombieJ</Option>
  40. <Option value="yesmeck">yesmeck</Option>
  41. </Mentions>,
  42. )}
  43. </Form.Item>
  44. <Form.Item label="Bio" labelCol={{ span: 6 }} wrapperCol={{ span: 16 }}>
  45. {getFieldDecorator('bio', {
  46. rules: [{ required: true }],
  47. })(
  48. <Mentions rows="3" placeholder="You can use @ to ref user here">
  49. <Option value="afc163">afc163</Option>
  50. <Option value="zombieJ">zombieJ</Option>
  51. <Option value="yesmeck">yesmeck</Option>
  52. </Mentions>,
  53. )}
  54. </Form.Item>
  55. <Form.Item wrapperCol={{ span: 14, offset: 6 }}>
  56. <Button type="primary" onClick={this.handleSubmit}>
  57. Submit
  58. </Button>
  59. &nbsp;&nbsp;&nbsp;
  60. <Button onClick={this.handleReset}>Reset</Button>
  61. </Form.Item>
  62. </Form>
  63. );
  64. }
  65. }
  66. const FormDemo = Form.create()(App);
  67. ReactDOM.render(<FormDemo />, mountNode);

Mentions提及 - 图3

无效或只读

通过 disabled 属性设置是否生效。通过 readOnly 属性设置是否只读。

  1. import { Mentions } from 'antd';
  2. const { Option } = Mentions;
  3. function getOptions() {
  4. return ['afc163', 'zombiej', 'yesmeck'].map(value => (
  5. <Option key={value} value={value}>
  6. {value}
  7. </Option>
  8. ));
  9. }
  10. function App() {
  11. return (
  12. <div>
  13. <div style={{ marginBottom: 10 }}>
  14. <Mentions style={{ width: '100%' }} placeholder="this is disabled Mentions" disabled>
  15. {getOptions()}
  16. </Mentions>
  17. </div>
  18. <Mentions style={{ width: '100%' }} placeholder="this is readOnly Mentions" readOnly>
  19. {getOptions()}
  20. </Mentions>
  21. </div>
  22. );
  23. }
  24. ReactDOM.render(<App />, mountNode);

Mentions提及 - 图4

异步加载

匹配内容列表为异步返回时。

  1. import { Mentions } from 'antd';
  2. import debounce from 'lodash/debounce';
  3. const { Option } = Mentions;
  4. class AsyncMention extends React.Component {
  5. constructor() {
  6. super();
  7. this.loadGithubUsers = debounce(this.loadGithubUsers, 800);
  8. }
  9. state = {
  10. search: '',
  11. loading: false,
  12. users: [],
  13. };
  14. onSearch = search => {
  15. this.setState({ search, loading: !!search, users: [] });
  16. console.log('Search:', search);
  17. this.loadGithubUsers(search);
  18. };
  19. loadGithubUsers(key) {
  20. if (!key) {
  21. this.setState({
  22. users: [],
  23. });
  24. return;
  25. }
  26. fetch(`https://api.github.com/search/users?q=${key}`)
  27. .then(res => res.json())
  28. .then(({ items = [] }) => {
  29. const { search } = this.state;
  30. if (search !== key) return;
  31. this.setState({
  32. users: items.slice(0, 10),
  33. loading: false,
  34. });
  35. });
  36. }
  37. render() {
  38. const { users, loading } = this.state;
  39. return (
  40. <Mentions style={{ width: '100%' }} loading={loading} onSearch={this.onSearch}>
  41. {users.map(({ login, avatar_url: avatar }) => (
  42. <Option key={login} value={login} className="antd-demo-dynamic-option">
  43. <img src={avatar} alt={login} />
  44. <span>{login}</span>
  45. </Option>
  46. ))}
  47. </Mentions>
  48. );
  49. }
  50. }
  51. ReactDOM.render(<AsyncMention />, mountNode);

Mentions提及 - 图5

自定义触发字符

通过 prefix 属性自定义触发字符。默认为 @, 可以定义为数组。

  1. import { Mentions } from 'antd';
  2. const { Option } = Mentions;
  3. const MOCK_DATA = {
  4. '@': ['afc163', 'zombiej', 'yesmeck'],
  5. '#': ['1.0', '2.0', '3.0'],
  6. };
  7. class App extends React.Component {
  8. state = {
  9. prefix: '@',
  10. };
  11. onSearch = (_, prefix) => {
  12. this.setState({ prefix });
  13. };
  14. render() {
  15. const { prefix } = this.state;
  16. return (
  17. <Mentions
  18. style={{ width: '100%' }}
  19. placeholder="input @ to mention people, # to mention tag"
  20. prefix={['@', '#']}
  21. onSearch={this.onSearch}
  22. >
  23. {(MOCK_DATA[prefix] || []).map(value => (
  24. <Option key={value} value={value}>
  25. {value}
  26. </Option>
  27. ))}
  28. </Mentions>
  29. );
  30. }
  31. }
  32. ReactDOM.render(<App />, mountNode);

Mentions提及 - 图6

向上展开

向上展开建议。

  1. import { Mentions } from 'antd';
  2. const { Option } = Mentions;
  3. ReactDOM.render(
  4. <Mentions style={{ width: '100%' }} placement="top">
  5. <Option value="afc163">afc163</Option>
  6. <Option value="zombieJ">zombieJ</Option>
  7. <Option value="yesmeck">yesmeck</Option>
  8. </Mentions>,
  9. mountNode,
  10. );

API

  1. <Mentions onChange={onChange}>
  2. <Mentions.Option value="sample">Sample</Mentions.Option>
  3. </Mentions>

Mentions

参数说明类型默认值版本
autoFocus自动获得焦点booleanfalse3.19.0
defaultValue默认值string-3.19.0
filterOption自定义过滤逻辑false | (input: string, option: OptionProps) => boolean-3.19.0
notFoundContent当下拉列表为空时显示的内容ReactNode'Not Found'3.19.0
placement弹出层展示位置'top' | 'bottom''bottom'3.19.0
prefix设置触发关键字string | string[]'@'3.19.0
split设置选中项前后分隔符string' '3.19.0
validateSearch自定义触发验证逻辑(text: string, props: MentionsProps) => void-3.19.0
value设置值string-3.19.0
onChange值改变时触发(text: string) => void-3.19.0
onSelect选择选项时触发(option: OptionProps, prefix: string) => void-3.19.0
onSearch搜索时触发(text: string, prefix: string) => void-3.19.0
onFocus获得焦点时触发() => void-3.19.0
onBlur失去焦点时触发() => void-3.19.0
getPopupContainer指定建议框挂载的 HTML 节点() => HTMLElement-3.22.0

Mentions 方法

名称描述版本
blur()移除焦点3.19.0
focus()获取焦点3.19.0

Option

参数说明类型默认值版本
children选项内容ReactNode-3.19.0
value选择时填充的值string''3.19.0