十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Ant Design Mentions 组件完全指南:触发式 @ 提及输入框的配置、事件与源码实现

Ant Design Mentions 组件完全指南:触发式 @ 提及输入框的配置、事件与源码实现 Ant Design Mentions 组件完全指南触发式 提及输入框的配置、事件与源码实现【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-designMentions 是 Ant Design当前仓库 components/mentions提供的提及 某人/某物输入组件底层基于 textarea 实现在用户输入等触发符后弹出候选建议下拉框。本文以 components/mentions/index.en-US.md 的官方 API 文档为主体结合 index.tsx 源码与demo/目录下全部示例系统讲解其全部配置项、事件回调、受控用法、Form 集成、语义化 DOM 定制以及底层实现原理帮助你从会用进阶到用得对、改得动。何时使用 Mentions当业务需要在输入过程中提及某人或某事物时使用 Mentions典型场景包括富文本评论区中用户并校验必须 到人工单/知识库正文中协作者、#引用标签或版本号邮件、IM 场景中按触发符联想通讯录联系人。它提供内联的输入与建议浮层交互与主流社交产品一致且天然适合放进 Form 表单做提及数量等规则校验。快速上手最小可用示例Mentions 的输入形式是 textarea选项通过options传入选中后文本以触发符 值的形式插入输入框中。仓库中最基础的示例见 demo/basic.tsximport React from react; import { Mentions } from antd; import type { GetProp, MentionProps } from antd; type MentionsOptionProps GetPropMentionProps, 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} defaultValueafc163 options{[ { value: afc163, label: afc163 }, { value: zombieJ, label: zombieJ }, { value: yesmeck, label: yesmeck }, ]} / ); export default App;几个必须理解的行为约定value/defaultValue是整个 textarea 的纯文本字符串被选中项会以value形式直接写入文本onChange回调收到的是包含触发符的完整文本。输入后开始触发联想候选数据由options提供OptionProps每个条目的核心字段为value与label详见下文 API 表。从源码看Mentions 是复合组件Mentions.Option子组件形式仍被支持但 index.tsx 在开发环境下会输出warning.deprecated(!children, Mentions.Option, options)即官方已不推荐用Mentions.Option写子节点统一改用options属性。输入框占位符使用原生placeholder行数与高度控制通过rows或autoSize完成。options 的静态用法与受控/非受控options数组可静态传入如上面的常量列表也可根据onSearch结果动态更新下一节异步加载。每个选项的数据结构即Option一节 API 表所列字段在 index.tsx 中options与children会统一归一化成 RcMentions 的options数据。候选数据结构Optionoptions中每个条目支持以下字段继承自 index.en-US.md 的 Option 表PropertyDescriptionTypeDefaultvalueValue inserted when selected被选中时插入输入框的值string-labelTitle of the option候选展示文案可为任意 ReactNode例如头像 昵称React.ReactNode-keyThe key value of the optionReact key用于列表协调string-disabledOptional禁用该候选boolean-classNameclassNamestring-styleThe style of the optionReact.CSSProperties-需要说明label支持复杂节点demo/async.tsx 中就把 GitHub 头像img与登录名拼进 labelkey未显式给出时框架会依据 value 兜底。value即最终插入文本建议与label语义一致避免用户困惑。触发符 prefix、分隔符 split 与 Mentions.getMentions默认触发符是单个但可以自定义多个。prefix支持string | string[]split是文本中一个提及项与下一个提及项之间的分隔字符串默认空格控制如何从整段文本切分出独立的提及项。多触发符动态切换示例官方示例 demo/prefix.tsx 演示了同时监听 人与## 版本号并在二者之间动态切换数据源import React, { useState } from react; import { Mentions } from antd; import type { MentionsProps } from antd; const MOCK_DATA { : [afc163, zombiej, yesmeck], #: [1.0, 2.0, 3.0], }; type PrefixType keyof typeof MOCK_DATA; const App: React.FC () { const [prefix, setPrefix] useStatePrefixType(); const onSearch: MentionsProps[onSearch] (_, newPrefix) { setPrefix(newPrefix as PrefixType); }; return ( Mentions style{{ width: 100% }} placeholderinput to mention people, # to mention tag prefix{[, #]} onSearch{onSearch} options{(MOCK_DATA[prefix] || []).map((value) ({ key: value, value, label: value, }))} / ); }; export default App;要点onSearch(text, prefix)的第二个参数就是当前命中的触发符据此切换数据源触发联想期间输入内容以触发符开头。静态方法 Mentions.getMentions 解析提及项Mentions 组件还挂载了一个静态方法Mentions.getMentions(value, config?)用于从纯文本中解析出所有提及实体其签名与行为由 index.tsx 实现config形如{ prefix , split }把value按split拆成若干段对每一段判断是否以某个prefix开头命中则去掉触发符得到实体value返回Array{ prefix: string; value: string }空实体触发符后无内容不进入结果。该方法最常见的用途是表单校验见下文 Form 集成也可用于提交前统计到底 了几个人。异步加载数据loading onSearch 防抖真实场景的候选人通常来自远端接口。官方 demo/async.tsx 演示了完整的异步方案onSearch触发请求、loading控制加载态、防抖减少请求次数并用闭包/ref 丢弃过期响应const [loading, setLoading] useState(false); const [users, setUsers] useState([]); const ref useRefstring(null); const loadGithubUsers (key: string) { if (!key) { setUsers([]); return; } fetch(https://api.github.com/search/users?q${key}) .then((res) res.json()) .then(({ items [] }) { // 仅当本次请求仍是最新关键字时才写入避免竞态 if (ref.current ! key) { return; } setLoading(false); setUsers(items.slice(0, 10)); }); }; const debounceLoadGithubUsers useCallback(debounce(loadGithubUsers, 800), []); const onSearch (search: string) { ref.current search; setLoading(!!search); setUsers([]); debounceLoadGithubUsers(search); }; Mentions loading{loading} onSearch{onSearch} options{/* 由 users 映射 */} /这里的工程要点loading 的加载态实现从源码 index.tsx 可见当loading为真时组件会把选项强制替换为一条value: ANTD_SEARCHING、disabled: true、label 为Spin sizesmall /的占位项filterOption也被替换为恒真函数loadingFilterOption并设置silent{loading}避免加载期误触发选择逻辑——加载态下的 UI 全部由 Mentions 内部接管你无需手动渲染 Spin。搜索关键字清空key为空时直接清空列表、不发起请求。竞态防护通过ref记录最新关键字迟到的旧响应直接丢弃。建议配合防抖示例使用 lodashdebounce(…, 800)避免每次按键都打接口。在 Form 中使用并结合 getMentions 做校验Mentions 原生支持 Form 表单接入。仓库示例 demo/form.tsx 展示了两种典型用法让 Mentions 作为受控表单项并用getMentions编写自定义校验规则至少 两个人import { Button, Form, Mentions, Space } from antd; const { getMentions } Mentions; const checkMention async (_: any, value: string) { const mentions getMentions(value); if (mentions.length 2) { throw new Error(More than one must be selected!); } }; Form form{form} onFinish{onFinish} Form.Item namecoders labelTop coders rules{[{ validator: checkMention }]} Mentions rows{1} options{options} / /Form.Item Form.Item namebio labelBio rules{[{ required: true }]} Mentions rows{3} placeholderYou can use to ref user here options{options} / /Form.Item /Form可复用的模式解构const { getMentions } MentionsgetMentions挂在组件上的静态方法见 index.tsx在 validator 里传入受控值字符串解析出{ prefix, value }[]根据长度/内容抛错配合 Form 展示校验状态校验失败时表单错误样式与表单状态会自动同步到 Mentions 上——这是因为 index.tsx 通过FormItemInputContext读取了外层 Form.Item 的status/hasFeedback/feedbackIcon并调用getMergedStatus(contextStatus, customStatus)合并出自定义与上下文状态。自动高度autoSizeMentions 基于 textarea因此支持自动增高特性autoSize可设为布尔值或对象{ minRows: 2, maxRows: 6 }可只提供其一见 demo/autoSize.tsxMentions autoSize style{{ width: 100% }} options{options} /行数上限与下限在输入换行时自动伸缩若希望固定可见行数用rows{1}/rows{3}demo/form.tsx 中两种用法都有体现。默认autoSize{false}此时高度固定为rows指定行数默认 1 行。组件还透传onResize({ width, height })供外部感知尺寸变化。一键清空allowClearallowClear默认false5.13.0 引入在输入框右侧渲染清除图标点击后清空整个文本值。它支持对象形态以自定义图标与禁用清除Mentions value{value} onChange{setValue} allowClear / Mentions value{value} onChange{setValue} allowClear{{ clearIcon: CloseSquareFilled / }} /完整演示见 demo/allowClear.tsx涉及三个细节clearIcon可传入任意 ReactNode 替换默认清除图标allowClear.disabled6.4.0控制清除按钮是否可用而onClear5.20.0在点击清除时回调内部通过useAllowClear来自 _util/hooks合并组件级与 ConfigProvider 上下文的allowClear配置全局默认defaultAllowClear: false从语义结构看清除图标属于 suffix 区见语义 DOM 一节。浮层行为placement、getPopupContainer、notFoundContent 与 popupRenderplacement建议浮层方向placement支持top|bottom默认bottom。设置为top时浮层向上展开适合输入框位于页面底部的布局示例 demo/placement.tsxMentions placementtop options{options} /类型定义见 index.tsx 的export type MentionPlacement top | bottom。挂载节点与空态getPopupContainer: () HTMLElement指定浮层挂载的 HTML 节点如滚动容器内需要自定义挂载以规避裁剪/层级问题时使用默认挂载到 body 附近。notFoundContent无匹配项时浮层展示的内容官方默认文案为No data从 index.tsx 的实现看未显式传入时实际会先走 ConfigProvider 的renderEmpty?.(Select)再回退到DefaultRenderEmpty因此也可以被全局Select 空态定制影响。popupRender深度定制下拉内容popupRender6.6.0接收渲染好的候选菜单menu: React.ReactElement返回任意 ReactNode常用于在候选列表上方加头部/提示/分隔线。官方 demo/popupRender.tsx 在菜单顶部加了一个自定义 HeaderMentions popupRender{(menu) ( div style{{ padding, fontWeight, color }}Custom Header/div Divider style{{ margin: 4px 0 }} / {menu} / )} options{options} /注意必须在渲染结果中包含传入的menu否则候选列表不会展示。源码侧 index.tsx 通过usePopupRender钩子归一化该钩子与 Select 共用同一实现并支持返回值自动包一层容器。onPopupScroll5.23.0可配合做下拉滚动到底加载更多。disabled 与 readOnly 的区别两者都禁止编辑但语义不同完整示例 demo/readonly.tsxdisabled整体置灰、不可聚焦输入、不可清除随 ConfigProvider 的DisabledContext上下文联动见 index.tsx 的mergedDisabled合并逻辑并为prefixCls-disabled添加语义类。readOnly仍可聚焦、文本仍可被选中复制只是不能修改浮层不弹出。代码层面两者的样式由variant类与状态类配合prefixCls-disabled/prefixCls-readonly等语义类控制。尺寸、形态与校验状态size / variant / statussize三种尺寸size取值large|medium|small默认跟随 ConfigProvider 的SizeContext通过useSize合并见 index.tsx并据此追加${prefixCls}-sm/${prefixCls}-lg样式类。官方 demo/size.tsx 展示了large/ 默认 /small三档对比。variant四种输入形态variant默认outlined支持outlined描边/filled填充/borderless无边框/underlined下划线四种形态demo/variant.tsx 依次演示Mentions placeholderOutlined / Mentions placeholderFilled variantfilled / Mentions placeholderBorderless variantborderless / Mentions placeholderUnderlined variantunderlined /版本历史outlined/filled/borderless自 5.13.0underlined自 5.24.0形态值同样可从 ConfigProvider 全局读取5.19.0 起属组件级全局配置useVariant处理合并与 Input 组件族共享同一套形态语义。status三种校验状态status4.19.0取值error|warning|success|validating覆盖输入框与浮层边框、focus 光环等视觉状态。demo/status.tsx 展示了error与warningMentions defaultValueafc163 statuserror options{options} / Mentions defaultValueafc163 statuswarning options{options} /内部由getMergedStatus(contextStatus, customStatus)合并 Form.Item 上下文状态后通过getStatusClassNames(prefixCls, mergedStatus)生成状态样式类index.tsx。若同时配置了hasFeedback后缀会渲染校验反馈图标suffix语义节点见 index.tsx。语义化 DOMclassNames 与 styles6.0.06.0.0 起 Mentions 支持对组件内部各语义节点做细粒度样式定制classNames与styles均可为对象或函数形态。语义节点来自 index.tsx 的类型定义与 demo/_semantic.tsx 的文档演示语义节点含义root根元素负责行内 flex 布局、相对定位、内边距与边框textarea内部文本域控制字体、行高、文本输入与背景popup候选浮层控制绝对定位、z-index、背景、圆角、阴影与下拉项suffix后缀元素容纳清除按钮、校验反馈图标等函数形态签名(info: { props }) RecordSemanticDOM, string | CSSProperties其中info.props为合并后的组件 props含 disabled/status/variant 等可据此做条件样式。官方示例 demo/style-class.tsx 同时演示了两种形态const stylesObject: MentionsProps[styles] { textarea: { fontSize: 14, resize: vertical, fontWeight: 200 }, }; const stylesFunction: MentionsProps[styles] (info) { if (info.props.variant filled) { return { root: { border: 1px solid #722ed1 }, popup: { border: 1px solid #722ed1 }, }; } }; Mentions styles{stylesObject} rows{2} / Mentions styles{stylesFunction} variantfilled /工程注意点支持 className 风格antd-stylecreateStyles生成的类名直接注入classNames实现把样式收敛到 cssinjs。popup 上还额外支持popupClassName属性追加类名index.tsx。若设置了rootClassName根元素与浮层都会带上该 class。从源码看浮层的 z-index 并非写死useZIndex(SelectLike, mergedStyles.popup?.zIndex)会在你传入的styles.popup.zIndex基础上处理层叠上下文index.tsx并将结果合并进实际 popup 样式。classNames/styles同样可以来自 ConfigProvider 的useComponentConfig(mentions)上下文实现整站统一的口径定制。API 完整参考Mention下述属性表完整继承自官方文档 components/mentions/index.en-US.mdPropertyDescriptionTypeDefaultVersionGlobal ConfigallowClearWhether to show a clear icon to remove mentions contentboolean | { clearIcon?: ReactNode, disabled?: boolean }false5.13.0, disabled: 6.4.06.4.0autoSizeTextarea height autosize feature, can be set to true | false or an object { minRows: 2, maxRows: 6 }boolean | objectfalse×classNamesCustomize class for each semantic structure inside the component. Supports object or function.RecordSemanticDOM, string | (info: { props }) RecordSemanticDOM, string-6.0.0defaultValueDefault valuestring-×filterOptionCustomize filter option logicfalse | (input: string, option: OptionProps) boolean-×getPopupContainerSet the mount HTML node for suggestions() HTMLElement-×notFoundContentSet mentions content when not matchReactNodeNo data×placementSet popup placementtop|bottombottom×popupRenderCustomize the dropdown menu rendering(menu: React.ReactElement) ReactNode-6.6.0×prefixSet trigger prefix keywordstring | string[]×splitSet split string before and after selected mentionstring×sizeThe size of the input boxlarge|medium|small-×statusSet validation statuserror | warning | success | validating-4.19.0×validateSearchCustomize trigger search logic(text: string, props: MentionsProps) void-×valueSet value of mentionsstring-×variantVariants of Inputoutlined|borderless|filled|underlinedoutlined5.13.0 |underlined: 5.24.05.19.0onBlurTrigger when mentions lose focus() void-×onChangeTrigger when value changed(text: string) void-×onClearCallback when click the clear button() void-5.20.0×onFocusTrigger when mentions get focus() void-×onResizeThe callback function that is triggered when textarea resizefunction({ width, height })-×onSearchTrigger when prefix hit(text: string, prefix: string) void-×onSelectTrigger when user select the option(option: OptionProps, prefix: string) void-×onPopupScrollTrigger when mentions scroll(e: Event) void-5.23.0×optionsOption ConfigurationOption[][]5.1.0×stylesCustomize inline style for each semantic structure inside the component. Supports object or function.RecordSemanticDOM, CSSProperties | (info: { props }) RecordSemanticDOM, CSSProperties-6.0.0上表阅读提示Global Config 一列有值的属性表示可通过 ConfigProvider 的组件级全局配置components.Mentions统一设置如variant、allowClear、classNames/styles值为×的属性只能实例级配置源码中useComponentConfig(mentions)index.tsx即负责读取该全局段配置。表格未单列的属性如prefixCls、rows、placeholder、disabled、readOnly、id、onKeyDown等 textarea 原生能力继续透传给底层。validateSearch用于自定义是否进入联想的判定逻辑默认行为是当前光标前的输入以prefix开头即触发。实例方法Mentions 转发 ref可通过useRefMentionsRef()调用实例方法index.tsx 的MentionsRef类型即RcMentionsRefNameDescriptionblur()Remove focus移除焦点focus()Get focus获取焦点典型用法点击外部按钮后调用mentionsRef.current?.focus()让输入框重新聚焦配合onFocus/onBlur内部还会同步focused状态以维护${prefixCls}-focused类见 index.tsx做聚焦态 UI。设计与样式定制Design Token文档中Design Token部分由ComponentTokenTable componentMentions /动态渲染其取值源头是本组件样式入口 style/index.ts内部使用 antd 的 cssinjs 接入ant-design/cssinjs风格体系返回hashId与 cssVar 类用于样式隔离。定制方式与其他组件一致通过ConfigProvider的theme.components.Mentions覆盖组件级 token如边框、浮层圆角/阴影、选项高亮色等token 元数据可在主题文档中查询Mentions 内部通过useStyle、useCSSVarCls挂载 hash 与 CSS 变量类index.tsx主题变化会自动反映到输入框与浮层仓库还维护了组件级渲染面板_InternalPanelDoNotUseOrYouWillBeFiredindex.tsx用于文档静态预览业务代码请勿使用。从源码看组件的整体装配最后把 index.tsx 中提到的关键组装逻辑串起来便于理解属性优先级与调试方向上下文优先级variant、size、disabled、allowClear、status均遵循实例属性 ConfigProvider 组件级配置 全局上下文Size/Disabled/Form.Item的合并顺序。空态回退notFoundContent未设置时回退到全局空态渲染可被 ConfigProvider 的renderEmpty定制。浮层层级popup z-index 走统一工具useZIndex(SelectLike, …)与 Select 一类组件保持一致的层叠秩序。加载态占位loading时不依赖外部数据也能呈现 Spin 占位与禁用选项。RTL 支持direction 为 rtl 时追加${prefixCls}-rtl类index.tsx。测试佐证仓库在 components/mentions/tests下提供了完整用例包括交互测试index.test.tsx、无障碍a11y.test.ts、语义化 DOMsemantic.test.tsx与全部 demo 的快照测试可作为行为契约参考。若需与受控输入、禁用态等常用属性的更多说明互相印证可对照 Common props 通用属性文档 与 Input 组件 的形态体系需要把 Mentions 与配置全局 theme/variant 组合使用时可参考 ConfigProvider 组件配置说明。至此从最小示例、异步加载、Form 校验到语义化 DOM 定制你已经掌握了 Mentions 组件的完整实战路径。【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-design创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表