Mentions提及
提及组件。
何时使用
用于在输入中提及某人或某事,常用于发布、聊天或评论功能。
代码演示

基本使用。
import { Mentions } from 'antd';const { Option } = Mentions;function onChange(value) {console.log('Change:', value);}function onSelect(option) {console.log('select', option);}ReactDOM.render(<Mentionsstyle={{ width: '100%' }}onChange={onChange}onSelect={onSelect}defaultValue="@afc163"><Option value="afc163">afc163</Option><Option value="zombieJ">zombieJ</Option><Option value="yesmeck">yesmeck</Option></Mentions>,mountNode,);

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

import { Mentions, Form, Button } from 'antd';const { Option, getMentions } = Mentions;const App = () => {const [form] = Form.useForm();const onReset = () => {form.resetFields();};const onFinish = async () => {try {const values = await form.validateFields();console.log('Submit:', values);} catch (errInfo) {console.log('Error:', errInfo);}};const checkMention = async (_: any, value: string) => {const mentions = getMentions(value);if (mentions.length < 2) {throw new Error('More than one must be selected!');}};return (<Form form={form} layout="horizontal" onFinish={onFinish}><Form.Itemname="coders"label="Top coders"labelCol={{ span: 6 }}wrapperCol={{ span: 16 }}rules={[{ validator: checkMention }]}><Mentions rows={1}><Option value="afc163">afc163</Option><Option value="zombieJ">zombieJ</Option><Option value="yesmeck">yesmeck</Option></Mentions></Form.Item><Form.Itemname="bio"label="Bio"labelCol={{ span: 6 }}wrapperCol={{ span: 16 }}rules={[{ required: true }]}><Mentions rows={3} placeholder="You can use @ to ref user here"><Option value="afc163">afc163</Option><Option value="zombieJ">zombieJ</Option><Option value="yesmeck">yesmeck</Option></Mentions></Form.Item><Form.Item wrapperCol={{ span: 14, offset: 6 }}><Button htmlType="submit" type="primary">Submit</Button> <Button htmlType="button" onClick={onReset}>Reset</Button></Form.Item></Form>);};ReactDOM.render(<App />, mountNode);

通过 disabled 属性设置是否生效。通过 readOnly 属性设置是否只读。
import { Mentions } from 'antd';const { Option } = Mentions;function getOptions() {return ['afc163', 'zombiej', 'yesmeck'].map(value => (<Option key={value} value={value}>{value}</Option>));}function App() {return (<><div style={{ marginBottom: 10 }}><Mentions style={{ width: '100%' }} placeholder="this is disabled Mentions" disabled>{getOptions()}</Mentions></div><Mentions style={{ width: '100%' }} placeholder="this is readOnly Mentions" readOnly>{getOptions()}</Mentions></>);}ReactDOM.render(<App />, mountNode);

自适应内容高度。
import { Mentions } from 'antd';const { Option } = Mentions;ReactDOM.render(<Mentions autoSize style={{ width: '100%' }}><Option value="afc163">afc163</Option><Option value="zombieJ">zombieJ</Option><Option value="yesmeck">yesmeck</Option></Mentions>,mountNode,);

匹配内容列表为异步返回时。
import { Mentions } from 'antd';import debounce from 'lodash/debounce';const { Option } = Mentions;class AsyncMention extends React.Component {constructor() {super();this.loadGithubUsers = debounce(this.loadGithubUsers, 800);}state = {search: '',loading: false,users: [],};onSearch = search => {this.setState({ search, loading: !!search, users: [] });console.log('Search:', search);this.loadGithubUsers(search);};loadGithubUsers(key) {if (!key) {this.setState({users: [],});return;}fetch(`https://api.github.com/search/users?q=${key}`).then(res => res.json()).then(({ items = [] }) => {const { search } = this.state;if (search !== key) return;this.setState({users: items.slice(0, 10),loading: false,});});}render() {const { users, loading } = this.state;return (<Mentions style={{ width: '100%' }} loading={loading} onSearch={this.onSearch}>{users.map(({ login, avatar_url: avatar }) => (<Option key={login} value={login} className="antd-demo-dynamic-option"><img src={avatar} alt={login} /><span>{login}</span></Option>))}</Mentions>);}}ReactDOM.render(<AsyncMention />, mountNode);

通过 prefix 属性自定义触发字符。默认为 @, 可以定义为数组。
import { Mentions } from 'antd';const { Option } = Mentions;const MOCK_DATA = {'@': ['afc163', 'zombiej', 'yesmeck'],'#': ['1.0', '2.0', '3.0'],};class App extends React.Component {state = {prefix: '@',};onSearch = (_, prefix) => {this.setState({ prefix });};render() {const { prefix } = this.state;return (<Mentionsstyle={{ width: '100%' }}placeholder="input @ to mention people, # to mention tag"prefix={['@', '#']}onSearch={this.onSearch}>{(MOCK_DATA[prefix] || []).map(value => (<Option key={value} value={value}>{value}</Option>))}</Mentions>);}}ReactDOM.render(<App />, mountNode);

向上展开建议。
import { Mentions } from 'antd';const { Option } = Mentions;ReactDOM.render(<Mentions style={{ width: '100%' }} placement="top"><Option value="afc163">afc163</Option><Option value="zombieJ">zombieJ</Option><Option value="yesmeck">yesmeck</Option></Mentions>,mountNode,);
API
<Mentions onChange={onChange}><Mentions.Option value="sample">Sample</Mentions.Option></Mentions>
Mentions
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| autoFocus | 自动获得焦点 | boolean | false |
| autoSize | 自适应内容高度,可设置为 true | false 或对象:{ minRows: 2, maxRows: 6 } | boolean | object | false |
| defaultValue | 默认值 | string | - |
| filterOption | 自定义过滤逻辑 | false | (input: string, option: OptionProps) => boolean | - |
| getPopupContainer | 指定建议框挂载的 HTML 节点 | () => HTMLElement | - |
| notFoundContent | 当下拉列表为空时显示的内容 | ReactNode | Not Found |
| placement | 弹出层展示位置 | top | bottom | bottom |
| prefix | 设置触发关键字 | string | string[] | @ |
| split | 设置选中项前后分隔符 | string | |
| validateSearch | 自定义触发验证逻辑 | (text: string, props: MentionsProps) => void | - |
| value | 设置值 | string | - |
| onBlur | 失去焦点时触发 | () => void | - |
| onChange | 值改变时触发 | (text: string) => void | - |
| onFocus | 获得焦点时触发 | () => void | - |
| onResize | resize 回调 | function({ width, height }) | - |
| onSearch | 搜索时触发 | (text: string, prefix: string) => void | - |
| onSelect | 选择选项时触发 | (option: OptionProps, prefix: string) => void | - |
Mentions 方法
| 名称 | 描述 |
|---|---|
| blur() | 移除焦点 |
| focus() | 获取焦点 |
Option
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| children | 选项内容 | ReactNode | - |
| value | 选择时填充的值 | string | - |
当前内容版权归 Ant Design 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 Ant Design .