news 2026/9/19 17:51:50

Ant Design Mentions 组件基本使用指南:从基础 demo 到源码级原理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Ant Design Mentions 组件基本使用指南:从基础 demo 到源码级原理

Ant Design Mentions 组件基本使用指南:从基础 demo 到源码级原理

【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design

导读

Mentions(提及)是 Ant Design 中用于「在输入中提及某人或某事」的核心录入组件,常见于发布、聊天与评论场景。本文以仓库中的 基本使用 demo 为起点,完整讲解其数据组织方式、事件回调、触发前缀与校验等实战能力,并结合 组件源码 与测试用例深入其底层实现。读完本文,你将掌握 Mentions 的声明式 options 用法、5.1.0 升级要点、静态工具方法getMentions的原理,以及如何与 Form 联动完成提及校验。

一、基本使用:一个完整的 Mentions 示例

仓库中 components/mentions/demo/basic.md 对它的描述只有一句话「基本使用」,但对应的 basic.tsx 是一份可直接运行的完整示例:

import React from 'react'; import { Mentions } from 'antd'; import type { GetProp, MentionProps } from 'antd'; type MentionsOptionProps = GetProp<MentionProps, 'options'>[number]; const onChange = (value: string) => { console.log('Change:', value); }; const onSelect = (option: MentionsOptionProps) => { console.log('select', option); }; const App: React.FC = () => ( <Mentions style={{ width: '100%' }} onChange={onChange} onSelect={onSelect} defaultValue="@afc163" options={[ { value: 'afc163', label: 'afc163' }, { value: 'zombieJ', label: 'zombieJ' }, { value: 'yesmeck', label: 'yesmeck' }, ]} /> ); export default App;

这段代码覆盖了 Mentions 最核心的四个使用要素:

  • 数据源:通过options传入候选列表,每一项包含value(选择时填充到输入框的值)与label(建议面板中展示的标题);
  • 回显值defaultValue="@afc163"表示初始文本,当用户输入@前缀时,组件会在光标附近弹出候选面板;
  • 变更监听onChange在文本值改变时触发,回调参数为完整的输入文本字符串;
  • 选中监听onSelect在用户选中某个选项时触发,回调参数为该选项对象。

注意 demo 中通过GetProp<MentionProps, 'options'>[number]提取了选项的元素类型,这样onSelect的参数就能获得完整的 TypeScript 类型推导,这是官方示例中推荐的类型写法。

二、数据驱动的 options 与 5.1.0 用法升级

在 5.1.0 之前,开发者需要手工拼接 JSX 来声明选项;5.1.0 之后官方推荐使用options数组的数据驱动写法,详见 组件文档「5.1.0 用法升级」:

// >=5.1.0 可用,推荐的写法 ✅ const options = [{ value: 'sample', label: 'sample' }]; return <Mentions options={options} />; // <5.1.0 可用,>=5.1.0 时不推荐 🙅🏻‍♀️ return ( <Mentions onChange={onChange}> <Mentions.Option value="sample">Sample</Mentions.Option> </Mentions> );

从源码看,旧写法并未被立即移除,而是通过警告机制提示迁移。在 index.tsx 中:

if (process.env.NODE_ENV !== 'production') { const warning = devUseWarning('Mentions'); warning.deprecated(!children, 'Mentions.Option', 'options'); }

即生产环境下无感知,开发环境下控制台会打印[antd: Mentions]Mentions.Optionis deprecated. Please useoptionsinstead.的警告。对应测试用例位于tests/index.test.tsx:

it('warning if use Mentions.Option', () => { // 断言输出上述废弃警告 });

数据驱动写法的另一优势是便于与异步数据源结合。参考 async.tsx demo:先在onSearch中发起请求,再通过options映射接口返回的数据,同时配合loading属性展示加载状态。

三、触发前缀 prefix、分隔符 split 与 getMentions 静态方法

Mentions 的默认触发前缀是@,但可以通过prefix配置为单个字符串或字符串数组,例如同时支持@提及人与#提及话题,见 prefix.tsx demo:

const MOCK_DATA = { '@': ['afc163', 'zombiej', 'yesmeck'], '#': ['1.0', '2.0', '3.0'], }; const App: React.FC = () => { const [prefix, setPrefix] = useState('@'); const onSearch: MentionsProps['onSearch'] = (_, newPrefix) => { setPrefix(newPrefix); }; return ( <Mentions placeholder="input @ to mention people, # to mention tag" prefix={['@', '#']} onSearch={onSearch} options={(MOCK_DATA[prefix] || []).map((value) => ({ key: value, value, label: value, }))} /> ); };

这里的onSearch回调签名为(text: string, prefix: string) => void,第二个参数正是当前命中的前缀,据此可以动态切换候选数据源。与之配套的split属性用于设置选中项前后的分隔符,默认值为空格。

组件还暴露了一个静态工具方法Mentions.getMentions(value, config),用于从一段文本中解析出所有提及实体。其实现位于 index.tsx 末尾:

Mentions.getMentions = (value = '', config: MentionsConfig = {}): MentionsEntity[] => { const { prefix = '@', split = ' ' } = config; const prefixList: string[] = Array.isArray(prefix) ? prefix : [prefix]; return value .split(split) .map((str = '') => { let hitPrefix: string | null = null; prefixList.some((prefixStr) => { const startStr = str.slice(0, prefixStr.length); if (startStr === prefixStr) { hitPrefix = prefixStr; return true; } return false; }); if (hitPrefix !== null) { return { prefix: hitPrefix, value: str.slice(hitPrefix.length) }; } return null; }) .filter((entity) => !!entity && !!entity.value); };

其解析逻辑可以概括为三步:按split分隔文本 → 对每个片段匹配前缀 → 返回{ prefix, value }实体(无前缀或值为空的片段被过滤)。测试用例验证了多前缀场景:

const mentions = getMentions('@light #bamboo cat', { prefix: ['@', '#'] }); // 返回 [{ prefix: '@', value: 'light' }, { prefix: '#', value: 'bamboo' }]

这一方法在提交前校验「是否提到了足够多的人」等场景中非常实用,例如 form.tsx demo 中用它实现自定义校验:

const checkMention = async (_: any, value: string) => { const mentions = getMentions(value); if (mentions.length < 2) { throw new Error('More than one must be selected!'); } };

四、事件回调体系与受控/非受控用法

Mentions 的事件体系围绕输入全流程设计,各回调的触发时机与参数如下表(摘自 组件 API 文档):

回调触发时机参数
onChange值改变时(text: string)
onSelect选中选项时(option: OptionProps, prefix: string)
onSearch触发前缀命中(搜索)时(text: string, prefix: string)
onFocus获得焦点时()
onBlur失去焦点时()
onClear点击清除按钮时(5.20.0+)()
onResize文本域尺寸变化时({ width, height })

在值的管理上,Mentions 同时支持非受控(defaultValue)与受控(value+onChange)两种模式。受控模式配合清除能力的使用方式见 allowClear.tsx demo:

const [value, setValue] = useState('hello world'); <Mentions value={value} onChange={setValue} allowClear /> <Mentions value={value} onChange={setValue} allowClear={{ clearIcon: <CloseSquareFilled /> }} /> <Mentions value={value} onChange={setValue} allowClear rows={3} />

allowClear自 5.13.0 起支持两种形态:布尔值true(使用默认清除图标)或对象{ clearIcon: <ReactNode> }(自定义清除图标)。在源码中它经由getAllowClear工具处理:const mergedAllowClear = getAllowClear(allowClear);

五、与 Form 的深度集成

Mentions 与 Form 组件天然集成,可以直接作为Form.Item的表单控件使用。完整示例见 form.tsx demo,其关键点包括:

<Form form={form} onFinish={onFinish}> <Form.Item name="coders" label="Top coders" rules={[{ validator: checkMention }]} > <Mentions rows={1} options={mentionOptions} /> </Form.Item> ... </Form>
  • 校验规则:利用getMentions在 validator 中检查提及数量,满足「必须选择多于一个」的业务约束;
  • 提交与重置form.validateFields()触发校验、form.resetFields()重置表单,均在onFinish中统一处理;
  • 上下文状态继承:从 index.tsx 可以看到,组件通过React.useContext(FormItemInputContext)自动继承 Form 的校验状态与反馈图标,通过getMergedStatus合并上下文状态与自定义status,因此无需额外配置即可展示 error/warning 样式,并能渲染hasFeedback反馈图标(实现于源码中的suffixNode)。

六、更多的形态控制:只读、位置、状态与变体

围绕基本使用,仓库还提供了若干可直接借鉴的形态控制 demo:

只读与禁用(readonly.tsx):通过disabled禁用整个组件,或readOnly保持可聚焦但不可编辑,两者适用于不同交互语义。

展开方向(placement.tsx demo):默认建议面板向bottom展开,当输入框位于页面底部时,可通过placement="top"改为向上展开,避免面板超出视口。

校验状态与形态变体status支持'error' | 'warning'(文档同时列出success/validating),用于在脱离 Form 的场景下手动标记校验状态;variant(5.13.0+)支持outlined(默认)、filledborderless三种形态。源码中通过useVariant('mentions', customVariant)解析形态,并依据上下文状态生成对应的状态样式类名。

七、从源码看 Mentions 的封装结构

Mentions 在 Ant Design 中是围绕rc-mentions的封装层,核心职责包括(见 index.tsx):

  1. 主题与样式getPrefixCls('mentions', customizePrefixCls)生成前缀类名,useStyle注入 CSS-in-JS 样式与 hashId,并支持wrapCSSVar包裹 CSS 变量;
  2. 空态兜底:未命中任何选项时,notFoundContent默认渲染renderEmpty?.('Select')(可通过 ConfigProvider 全局定制),对应DefaultRenderEmpty
  3. 加载态loading为 true 时强制以Spin占位并禁用过滤(filterOption被替换为恒返回 true 的loadingFilterOption),同时silent传入底层避免触发搜索;
  4. 扩展能力Mentions.Option静态子组件、_InternalPanelDoNotUseOrYouWillBeFired调试面板(由genPurePanel生成)、getMentions静态方法共同构成复合组件形态。

测试方面,tests/index.test.tsx 覆盖了getMentions解析、loading渲染、notFoundContentallowClear(含自定义clearIcon)、Mentions.Option废弃警告、focus/blur 事件等关键行为,可作为你验证自定义改造时的参考依据。

结语

从一行basic.md出发,Mentions 组件实际上承载了数据驱动选项、多前缀触发、文本解析工具、Form 校验联动与多形态控制等完整能力。本文所有代码均可从仓库中的 demo 目录 直接找到可运行版本,组件完整 API 参数表请参阅 index.zh-CN.md 与 index.en-US.md,深入实现可阅读 index.tsx。

【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 17:50:31

Demosaic算法全解析:从双线性插值到深度学习与FPGA实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 17:49:10

Hugo 站点数据访问指南:Site.Data 方法详解与 hugo.Data 迁移实践

开发工具前端CLI 【免费下载链接】hugo The world’s fastest framework for building websites. 项目地址&#xff1a; https://gitcode.com/gh_mirrors/hu/hugo 点击查看 免费下载 Site.Data 返回由 data 目录&#xff08;或挂载到 data 目录的任何目录&#xff09;中全部文…

作者头像 李华
网站建设 2026/9/19 17:49:01

Google AI Pro 订阅深度评测:$19.99 的 Gemini 与 Google 生态整合值不值

1. 这个订阅到底在卖什么&#xff1a;先看清 Google AI Pro 的真实定位$19.99 一个月&#xff0c;这个价格放在当下的 AI 订阅市场里&#xff0c;属于“中档偏上”的位置。比免费版强不少&#xff0c;但又没到企业级方案那种动辄按席位、按调用量计费的程度。很多人第一次看到 …

作者头像 李华
网站建设 2026/9/19 17:48:56

VMware与Hyper-V冲突根源及精准解除方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 17:48:49

ChromeDriver版本匹配原理与自动化管理方案

1. 别再搜“ChromeDriver下载”了——你真正需要的不是地址&#xff0c;而是判断逻辑我见过太多人卡在自动化测试的第一步&#xff1a;下载ChromeDriver。不是不会写Selenium代码&#xff0c;不是搞不定元素定位&#xff0c;而是花20分钟反复刷新各种博客、论坛、第三方网盘链接…

作者头像 李华