• Mention提及
    • 何时使用
    • 代码演示
    • API
      • Mention API
      • Mention
      • Mention 方法
      • Nav

    Mention提及

    提及组件。

    何时使用

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

    代码演示

    Mention 提及 - 图1

    基本使用

    基本使用

    1. import { Mention } from 'antd';
    2. const { toString, toContentState } = Mention;
    3. function onChange(contentState) {
    4. console.log(toString(contentState));
    5. }
    6. function onSelect(suggestion) {
    7. console.log('onSelect', suggestion);
    8. }
    9. ReactDOM.render(
    10. <Mention
    11. style={{ width: '100%' }}
    12. onChange={onChange}
    13. defaultValue={toContentState('@afc163')}
    14. defaultSuggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']}
    15. onSelect={onSelect}
    16. />,
    17. mountNode,
    18. );

    Mention 提及 - 图2

    异步加载

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

    1. import { Mention } from 'antd';
    2. const users = ['afc163', 'benjycui', 'yiminghe', 'jljsj33', 'dqaria', 'RaoHai'];
    3. class AsyncMention extends React.Component {
    4. state = {
    5. suggestions: [],
    6. loading: false,
    7. };
    8. fetchSuggestions = (value, callback) => {
    9. setTimeout(() => {
    10. callback(users.filter(item => item.indexOf(value) !== -1));
    11. }, 500);
    12. };
    13. onSearchChange = value => {
    14. this.fetchSuggestions(value, suggestions => {
    15. this.setState({
    16. suggestions,
    17. loading: false,
    18. });
    19. });
    20. this.setState({
    21. loading: true,
    22. });
    23. };
    24. render() {
    25. const { suggestions, loading } = this.state;
    26. return (
    27. <Mention
    28. style={{ width: '100%' }}
    29. loading={loading}
    30. suggestions={suggestions}
    31. onSearchChange={this.onSearchChange}
    32. />
    33. );
    34. }
    35. }
    36. ReactDOM.render(<AsyncMention />, mountNode);

    Mention 提及 - 图3

    头像

    自定义建议(含头像)

    注意,自定义建议时,onSearchChange 必须不能为空。

    1. import { Mention, Avatar } from 'antd';
    2. const Nav = Mention.Nav;
    3. const webFrameworks = [
    4. {
    5. name: 'React',
    6. type: 'JavaScript',
    7. icon: 'https://zos.alipayobjects.com/rmsportal/LFIeMPzdLcLnEUe.svg',
    8. },
    9. {
    10. name: 'Angular',
    11. type: 'JavaScript',
    12. icon: 'https://zos.alipayobjects.com/rmsportal/PJTbxSvzYWjDZnJ.png',
    13. },
    14. {
    15. name: 'Dva',
    16. type: 'Javascript',
    17. icon: 'https://zos.alipayobjects.com/rmsportal/EYPwSeEJKxDtVxI.png',
    18. },
    19. {
    20. name: 'Flask',
    21. type: 'Python',
    22. icon: 'https://zos.alipayobjects.com/rmsportal/xaypBUijfnpAlXE.png',
    23. },
    24. ];
    25. class CustomNavMention extends React.Component {
    26. state = {
    27. suggestions: [],
    28. };
    29. onSearchChange = value => {
    30. const searchValue = value.toLowerCase();
    31. const filtered = webFrameworks.filter(
    32. item => item.name.toLowerCase().indexOf(searchValue) !== -1,
    33. );
    34. const suggestions = filtered.map(suggestion => (
    35. <Nav value={suggestion.name} data={suggestion} disabled={suggestion.disabled}>
    36. <Avatar
    37. src={suggestion.icon}
    38. size="small"
    39. style={{
    40. width: 14,
    41. height: 14,
    42. marginRight: 8,
    43. top: -1,
    44. position: 'relative',
    45. }}
    46. />
    47. {suggestion.name} - {suggestion.type}
    48. </Nav>
    49. ));
    50. this.setState({ suggestions });
    51. };
    52. render() {
    53. const { suggestions } = this.state;
    54. return (
    55. <Mention
    56. style={{ width: '100%' }}
    57. suggestions={suggestions}
    58. onSearchChange={this.onSearchChange}
    59. />
    60. );
    61. }
    62. }
    63. ReactDOM.render(<CustomNavMention />, mountNode);

    Mention 提及 - 图4

    配合 Form 使用

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

    1. import { Mention, Form, Button } from 'antd';
    2. const { toContentState, getMentions } = Mention;
    3. const FormItem = Form.Item;
    4. class App extends React.Component {
    5. state = {
    6. initValue: toContentState('@afc163'),
    7. };
    8. handleReset = e => {
    9. e.preventDefault();
    10. this.props.form.resetFields();
    11. };
    12. handleSubmit = e => {
    13. e.preventDefault();
    14. this.props.form.validateFields((errors, values) => {
    15. if (errors) {
    16. console.log('Errors in the form!!!');
    17. return;
    18. }
    19. console.log('Submit!!!');
    20. console.log(values);
    21. });
    22. };
    23. checkMention = (rule, value, callback) => {
    24. const { getFieldValue } = this.props.form;
    25. const mentions = getMentions(getFieldValue('mention'));
    26. if (mentions.length < 2) {
    27. callback(new Error('More than one must be selected!'));
    28. } else {
    29. callback();
    30. }
    31. };
    32. render() {
    33. const { getFieldDecorator, getFieldValue } = this.props.form;
    34. console.log('>> render', getFieldValue('mention') === this.state.initValue);
    35. return (
    36. <Form layout="horizontal">
    37. <FormItem
    38. id="control-mention"
    39. label="Top coders"
    40. labelCol={{ span: 6 }}
    41. wrapperCol={{ span: 16 }}
    42. >
    43. {getFieldDecorator('mention', {
    44. rules: [{ validator: this.checkMention }],
    45. initialValue: this.state.initValue,
    46. })(
    47. <Mention
    48. defaultSuggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']}
    49. />,
    50. )}
    51. </FormItem>
    52. <FormItem wrapperCol={{ span: 14, offset: 6 }}>
    53. <Button type="primary" onClick={this.handleSubmit}>
    54. Submit
    55. </Button>
    56. &nbsp;&nbsp;&nbsp;
    57. <Button onClick={this.handleReset}>Reset</Button>
    58. </FormItem>
    59. </Form>
    60. );
    61. }
    62. }
    63. const FormDemo = Form.create()(App);
    64. ReactDOM.render(<FormDemo />, mountNode);

    Mention 提及 - 图5

    建议渲染父节点

    指定提示渲染的父节点。

    1. import { Mention, Popover, Button } from 'antd';
    2. const { toString, toContentState } = Mention;
    3. function onChange(editorState) {
    4. console.log(toString(editorState));
    5. }
    6. function onSelect(suggestion) {
    7. console.log('onSelect', suggestion);
    8. }
    9. class PopoverContainer extends React.Component {
    10. getSuggestionContainer = () => this.popover.getPopupDomNode();
    11. visibleChange = visible => {
    12. if (visible && this.mention) {
    13. this.mention.focus();
    14. }
    15. };
    16. render() {
    17. const mention = (
    18. <Mention
    19. ref={ele => (this.mention = ele)}
    20. style={{ width: '100%' }}
    21. onChange={onChange}
    22. defaultValue={toContentState('@afc163')}
    23. defaultSuggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']}
    24. onSelect={onSelect}
    25. getSuggestionContainer={this.getSuggestionContainer}
    26. />
    27. );
    28. return (
    29. <Popover
    30. trigger="click"
    31. content={mention}
    32. title="Title"
    33. ref={popover => (this.popover = popover)}
    34. onVisibleChange={this.visibleChange}
    35. >
    36. <Button type="primary">Click Me</Button>
    37. </Popover>
    38. );
    39. }
    40. }
    41. ReactDOM.render(<PopoverContainer />, mountNode);

    Mention 提及 - 图6

    自定义触发字符

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

    1. import { Mention } from 'antd';
    2. const { toString } = Mention;
    3. function onChange(editorState) {
    4. console.log(toString(editorState));
    5. }
    6. function onSelect(suggestion) {
    7. console.log('onSelect', suggestion);
    8. }
    9. const users = ['afc163', 'benjycui', 'yiminghe', 'jljsj33', 'dqaria', 'RaoHai'];
    10. const tags = ['1.0', '2.0', '3.0'];
    11. class App extends React.Component {
    12. constructor() {
    13. super();
    14. this.state = {
    15. suggestions: [],
    16. };
    17. }
    18. onSearchChange = (value, trigger) => {
    19. console.log('onSearchChange', value, trigger);
    20. const dataSource = trigger === '@' ? users : tags;
    21. this.setState({
    22. suggestions: dataSource.filter(item => item.indexOf(value) !== -1),
    23. });
    24. };
    25. render() {
    26. return (
    27. <Mention
    28. style={{ width: '100%' }}
    29. onChange={onChange}
    30. placeholder="input @ to mention people, # to mention tag"
    31. prefix={['@', '#']}
    32. onSearchChange={this.onSearchChange}
    33. suggestions={this.state.suggestions}
    34. onSelect={onSelect}
    35. />
    36. );
    37. }
    38. }
    39. ReactDOM.render(<App />, mountNode);

    Mention 提及 - 图7

    向上展开

    向上展开建议。

    1. import { Mention } from 'antd';
    2. const { toString } = Mention;
    3. function onChange(contentState) {
    4. console.log(toString(contentState));
    5. }
    6. function onSelect(suggestion) {
    7. console.log('onSelect', suggestion);
    8. }
    9. ReactDOM.render(
    10. <Mention
    11. style={{ width: '100%' }}
    12. onChange={onChange}
    13. defaultSuggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']}
    14. onSelect={onSelect}
    15. placement="top"
    16. />,
    17. mountNode,
    18. );

    Mention 提及 - 图8

    自定义建议

    自定义建议

    注意,自定义建议时,onSearchChange 必须不能为空。

    1. import { Mention } from 'antd';
    2. const Nav = Mention.Nav;
    3. const webFrameworks = [
    4. { name: 'React', type: 'JavaScript' },
    5. { name: 'Angular', type: 'JavaScript' },
    6. { name: 'Laravel', type: 'PHP', disabled: true },
    7. { name: 'Flask', type: 'Python' },
    8. { name: 'Django', type: 'Python' },
    9. ];
    10. function onSelect(suggestion, data) {
    11. console.log('onSelect', suggestion, data);
    12. }
    13. class CustomNavMention extends React.Component {
    14. state = {
    15. suggestions: [],
    16. };
    17. onSearchChange = value => {
    18. const searchValue = value.toLowerCase();
    19. const filtered = webFrameworks.filter(
    20. item => item.name.toLowerCase().indexOf(searchValue) !== -1,
    21. );
    22. const suggestions = filtered.map(suggestion => (
    23. <Nav value={suggestion.name} data={suggestion}>
    24. <span>
    25. {suggestion.name} - {suggestion.type}
    26. </span>
    27. </Nav>
    28. ));
    29. this.setState({ suggestions });
    30. };
    31. render() {
    32. const { suggestions } = this.state;
    33. return (
    34. <Mention
    35. placeholder="@someone"
    36. style={{ width: '100%' }}
    37. suggestions={suggestions}
    38. onSearchChange={this.onSearchChange}
    39. onSelect={onSelect}
    40. />
    41. );
    42. }
    43. }
    44. ReactDOM.render(<CustomNavMention />, mountNode);

    Mention 提及 - 图9

    受控模式

    受控模式.

    1. import { Mention } from 'antd';
    2. const { toContentState } = Mention;
    3. class App extends React.Component {
    4. state = {
    5. value: toContentState('@afc163'),
    6. };
    7. componentDidMount() {
    8. this.mention.focus();
    9. }
    10. handleChange = editorState => {
    11. this.setState({
    12. value: editorState,
    13. });
    14. };
    15. render() {
    16. return (
    17. <Mention
    18. ref={ele => (this.mention = ele)}
    19. defaultSuggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']}
    20. value={this.state.value}
    21. onChange={this.handleChange}
    22. />
    23. );
    24. }
    25. }
    26. ReactDOM.render(<App />, mountNode);

    Mention 提及 - 图10

    多行

    多行模式,多行模式必须指定高度。

    1. import { Mention } from 'antd';
    2. const { toString } = Mention;
    3. function onChange(editorState) {
    4. console.log(toString(editorState));
    5. }
    6. ReactDOM.render(
    7. <Mention
    8. style={{ width: '100%', height: 100 }}
    9. onChange={onChange}
    10. defaultSuggestions={['afc163', 'benjycui', 'yiminghe', 'jljsj33', 'dqaria', 'RaoHai']}
    11. multiLines
    12. />,
    13. mountNode,
    14. );

    Mention 提及 - 图11

    无效或只读

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

    1. import { Mention } from 'antd';
    2. const { toString } = Mention;
    3. function onChange(editorState) {
    4. console.log(toString(editorState));
    5. }
    6. const users = ['afc163', 'benjycui', 'yiminghe', 'jljsj33', 'dqaria', 'RaoHai'];
    7. function App() {
    8. return (
    9. <div>
    10. <div style={{ marginBottom: 10 }}>
    11. <Mention
    12. style={{ width: '100%' }}
    13. onChange={onChange}
    14. placeholder="this is disabled Mention"
    15. suggestions={users}
    16. disabled
    17. />
    18. </div>
    19. <Mention
    20. style={{ width: '100%' }}
    21. onChange={onChange}
    22. placeholder="this is readOnly Mention"
    23. suggestions={users}
    24. readOnly
    25. />
    26. </div>
    27. );
    28. }
    29. ReactDOM.render(<App />, mountNode);

    API

    1. <Mention
    2. onChange={onChange}
    3. suggestions={['afc163', 'benjycui', 'yiminghe', 'jljsj33', 'dqaria', 'RaoHai']}
    4. />

    Mention API

    API说明类型
    getMentions获取当前 contentState 中提到的人的列表Function(contentState: ContentState): string[]
    toContentState把字符串转成 ContentStateFunction(value: string): ContentState
    toString把 ContentState 转成字符串Function(contentState: ContentState): string

    Mention

    参数说明类型默认值
    autoFocus自动获取焦点booleanfalse
    defaultValue默认值ContentState, 可以用 Mention.toContentState(text) 把文字转换成 ContentStatenull
    defaultSuggestions默认建议内容Array<string|Mention.Nav>[]
    disabled是否禁用状态.booleanfalse
    getSuggestionContainer菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位function()() => document.body
    loading加载中booleanfalse
    multiLines多行模式booleanfalse
    notFoundContent未找到时的内容string'无匹配结果,轻敲空格完成输入'
    placeholder输入框默认文字stringnull
    placement建议框位置,可选 top bottomstring'bottom'
    prefix触发弹出下拉框的字符string or Array<string>'@'
    readOnly是否只读.booleanfalse
    suggestions建议内容Array<string|Mention.Nav>[]
    suggestionStyle弹出下拉框样式object{}
    valueContentStatenull
    onBlur失去焦点时回调function(e)null
    onChange输入框内容变化时回调function(contentState: ContentState)null
    onFocus获得焦点时回调function(e)null
    onSearchChange输入框中 @ 变化时回调function(value:string, trigger: string)[]
    onSelect下拉框选择建议时回调function(suggestion: string, data?: any)null

    Mention 方法

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

    Nav

    参数说明类型默认值
    children建议内容object{}
    value建议值,选择建议时,用此值插入到输入框中string""