Mentions提及

提及组件。

何时使用

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

代码演示

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 使用。

TypeScript

JavaScript

  1. import { Mentions, Form, Button } from 'antd';
  2. const { Option, getMentions } = Mentions;
  3. const App = () => {
  4. const [form] = Form.useForm();
  5. const onReset = () => {
  6. form.resetFields();
  7. };
  8. const onFinish = async () => {
  9. try {
  10. const values = await form.validateFields();
  11. console.log('Submit:', values);
  12. } catch (errInfo) {
  13. console.log('Error:', errInfo);
  14. }
  15. };
  16. const checkMention = async (rule, value, callback) => {
  17. const mentions = getMentions(value);
  18. if (mentions.length < 2) {
  19. throw new Error('More than one must be selected!');
  20. }
  21. };
  22. return (
  23. <Form form={form} layout="horizontal" onFinish={onFinish}>
  24. <Form.Item
  25. name="coders"
  26. label="Top coders"
  27. labelCol={{ span: 6 }}
  28. wrapperCol={{ span: 16 }}
  29. rules={[{ validator: checkMention }]}
  30. >
  31. <Mentions rows="1">
  32. <Option value="afc163">afc163</Option>
  33. <Option value="zombieJ">zombieJ</Option>
  34. <Option value="yesmeck">yesmeck</Option>
  35. </Mentions>
  36. </Form.Item>
  37. <Form.Item
  38. name="bio"
  39. label="Bio"
  40. labelCol={{ span: 6 }}
  41. wrapperCol={{ span: 16 }}
  42. rules={[{ required: true }]}
  43. >
  44. <Mentions rows="3" placeholder="You can use @ to ref user here">
  45. <Option value="afc163">afc163</Option>
  46. <Option value="zombieJ">zombieJ</Option>
  47. <Option value="yesmeck">yesmeck</Option>
  48. </Mentions>
  49. </Form.Item>
  50. <Form.Item wrapperCol={{ span: 14, offset: 6 }}>
  51. <Button htmlType="submit" type="primary">
  52. Submit
  53. </Button>
  54. &nbsp;&nbsp;&nbsp;
  55. <Button htmlType="button" onClick={onReset}>
  56. Reset
  57. </Button>
  58. </Form.Item>
  59. </Form>
  60. );
  61. };
  62. ReactDOM.render(<App />, 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自动获得焦点booleanfalse
defaultValue默认值string
filterOption自定义过滤逻辑false | (input: string, option: OptionProps) => boolean
notFoundContent当下拉列表为空时显示的内容ReactNode'Not Found'
placement弹出层展示位置top | bottombottom
prefix设置触发关键字string | string[]'@'
split设置选中项前后分隔符string' '
validateSearch自定义触发验证逻辑(text: string, props: MentionsProps) => void
value设置值string
onChange值改变时触发(text: string) => void
onSelect选择选项时触发(option: OptionProps, prefix: string) => void
onSearch搜索时触发(text: string, prefix: string) => void
onFocus获得焦点时触发() => void
onBlur失去焦点时触发() => void
getPopupContainer指定建议框挂载的 HTML 节点() => HTMLElement

Mentions 方法

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

Option

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