Ant Design学习——Mentions

Ant Design学习——Mentions2021SC SDUSC Mentions 提及 用法 用于在输入中提及某人或某事 常用于发布 聊天或评论功能 API mentions onchange onChange mentions option value sample Sample lt mentions option mentions

大家好,我是讯享网,很高兴认识大家。

2021SC@SDUSC

Mentions提及

API
<Mentions onChange={onChange}> <Mentions.Option value="sample">Sample</Mentions.Option> </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 -
部分源码
讯享网import * as React from 'react'; import classNames from 'classnames'; import RcMentions from 'rc-mentions'; import { 
    MentionsProps as RcMentionsProps } from 'rc-mentions/lib/Mentions'; import { 
    composeRef } from 'rc-util/lib/ref'; import Spin from '../spin'; import { 
    ConfigContext } from '../config-provider'; export const { 
    Option } = RcMentions; 
function loadingFilterOption() { 
    return true; } 

启用自定义过滤逻辑

讯享网export type MentionPlacement = 'top' | 'bottom'; 

弹开层的展开位置


讯享网

export interface OptionProps { 
    value: string; children: React.ReactNode; [key: string]: any; } export interface MentionProps extends RcMentionsProps { 
    loading?: boolean; } export interface MentionState { 
    focused: boolean; } interface MentionsConfig { 
    prefix?: string | string[]; split?: string; } interface MentionsEntity { 
    prefix: string; value: string; } 

设置选项接口、选中状态、触发关键字、选中项前后分隔符、提及实体等接口

讯享网interface CompoundedComponent extends React.ForwardRefExoticComponent<MentionProps & React.RefAttributes<HTMLElement>> { 
    Option: typeof Option; getMentions: (value: string, config?: MentionsConfig) => MentionsEntity[]; } 

此处运用到了ForwardRefExoticComponent

interface ExoticComponent<P = { 
    }> { 
    / * NOTE: Exotic components are not callable. */ (props: P): (ReactElement|null); readonly $$typeof: symbol; } interface NamedExoticComponent<P = { 
    }> extends ExoticComponent<P> { 
    displayName?: string; } interface ForwardRefExoticComponent<P> extends NamedExoticComponent<P> { 
    defaultProps?: Partial<P>; propTypes?: WeakValidationMap<P>; } 

ForwardRefRenderFunction主要区别在于

  • ForwardRefRenderFunction不支持propType和defaultProps,而ForwardRefExoticComponent则支持
  • ForwardRefExoticComponent有一个额外的typeof成员
  • ForwardRefRenderFunction调用签名中有一个props对象,必需包含一个children成员以及一个ref对象作为参数,而ForwardRefExoticComponent的调用签名中只需要一个props对象的任意形式作为参数
讯享网interface ForwardRefRenderFunction<T, P = { 
    }> { 
    (props: PropsWithChildren<P>, ref: ((instance: T | null) => void) | MutableRefObject<T | null> | null): ReactElement | null; displayName?: string; defaultProps?: never; propTypes?: never; } 

以上为ForwardRefRenderFunction作为参照

const InternalMentions: React.ForwardRefRenderFunction<unknown, MentionProps> = ( { 
    prefixCls: customizePrefixCls, className, disabled, loading, filterOption, children, notFoundContent, ...restProps }, ref, ) => { 
    const [focused, setFocused] = React.useState(false); const innerRef = React.useRef<HTMLElement>(); const mergedRef = composeRef(ref, innerRef); const { 
    getPrefixCls, renderEmpty, direction } = React.useContext(ConfigContext); const onFocus: React.FocusEventHandler<HTMLTextAreaElement> = (...args) => { 
    if (restProps.onFocus) { 
    restProps.onFocus(...args); } setFocused(true); }; const onBlur: React.FocusEventHandler<HTMLTextAreaElement> = (...args) => { 
    if (restProps.onBlur) { 
    restProps.onBlur(...args); } setFocused(false); }; const getNotFoundContent = () => { 
    if (notFoundContent !== undefined) { 
    return notFoundContent; } return renderEmpty('Select'); }; const getOptions = () => { 
    if (loading) { 
    return ( <Option value="ANTD_SEARCHING" disabled> <Spin size="small" /> </Option> ); } return children; }; const getFilterOption = (): any => { 
    if (loading) { 
    return loadingFilterOption; } return filterOption; }; const prefixCls = getPrefixCls('mentions', customizePrefixCls); const mergedClassName = classNames( { 
    [`${ 
     prefixCls}-disabled`]: disabled, [`${ 
     prefixCls}-focused`]: focused, [`${ 
     prefixCls}-rtl`]: direction === 'rtl', }, className, ); return ( <RcMentions prefixCls={ 
   prefixCls} notFoundContent={ 
   getNotFoundContent()} className={ 
   mergedClassName} disabled={ 
   disabled} direction={ 
   direction} { 
   ...restProps} filterOption={ 
   getFilterOption()} onFocus={ 
   onFocus} onBlur={ 
   onBlur} ref={ 
   mergedRef as any} > { 
   getOptions()} </RcMentions> ); }; const Mentions = React.forwardRef<unknown, MentionProps>(InternalMentions) as CompoundedComponent; Mentions.displayName = 'Mentions'; Mentions.Option = Option; Mentions.getMentions = (value: string = '', config?: MentionsConfig): MentionsEntity[] => { 
    const { 
    prefix = '@', split = ' ' } = config || { 
   }; const prefixList: string[] = Array.isArray(prefix) ? prefix : [prefix]; return value .split(split) .map((str = ''): MentionsEntity | null => { 
    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 as string).length), }; } return null; }) .filter((entity): entity is MentionsEntity => !!entity && !!entity.value); }; export default Mentions; 
小讯
上一篇 2025-03-06 14:23
下一篇 2025-03-30 09:21

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/44630.html