zoukankan      html  css  js  c++  java
  • AntD Select + AutoComplete

    简单介绍一下 AntD Select 的用法

    mode: undefined, tag, multiple

    • undefine: 默认值,就是dropdown,
    • tag: 跟multple 唯一的区别就是,输入的值不在list 内,敲回车,自动插入.
    • multiple, 就是多值选择。

    一些约定

    • showSearch: 看这段代码 const mergedShowSearch = showSearch !== undefined ? showSearch : isMultiple || mode === 'combobox'; 结论: 如果显示设置,优先级最高,隐含的其次,也就是 tags, multiple, combobox 也是可以showSearch.
      • 类似的开关还有很多,例如: showArrow 在其他的组件中,这个约定也是类似的。当然这些开关只是第一层,开关,默认有这个开关就可以打开,但是也有一些相关的属性进一步控制这个开关,例如 filterOption=false 就可以关闭search的功能,这个在SearchBox 或者Email 这种组件中使用。例如以下代码,尽管,我们打开了showSearch 开关,但是我们通过filterOption={false}关闭了该功能,我们通过onSearchevent来刷新options
    const options = this.state.data.map(d => <Option key={d.value}>{d.text}</Option>);
    <Select
            showSearch
            value={this.state.value}
            placeholder={this.props.placeholder}
            showArrow={false}
            filterOption={false}
            onSearch={this.handleSearch}
            onChange={this.handleChange}
            notFoundContent={null}
          >
            {options}
          </Select>
    

    谈谈 Select 里面的animation.

    首先,我们可以通过transitionName 参数来提供一个transtionName, 看这段代码:transitionName={getTransitionName(rootPrefixCls, 'slide-up', props.transitionName)}, 如果不提供,默认就是slide-up 这个transitionName,
    第一个问题,这个transtionName 有神马用途,或者,用它会发生什么,首先它会传递个CSSMotion ,如果有同学对CSSMotion 不理解,参考CSSMotion.
    简单说一下,下来菜单在展开或者关闭的过程,className 会如此变化。

    • 展开
      • .ant-slide-up-enter(Dom 已经存在) 或者 .ant-slide-up-appear(Dom 刚刚创建)
      • .ant-slide-up-enter-(prepare/start/active) 依次发生变化, 一般我们只关心start 与active
      • 最后动画结束,与动画相关的类名全部移除。
    • 关闭
      • .ant-slide-leave
      • .ant-slide-up-leave-(parepare/start/active) 依次发生,同样,我们只关心start 跟active
      • 最后动画结束,与动画相关的类名全部移除,附加上ant-select-dropdown-hidden 类.

    下面是slide-up 相关的css ,变化的就是opacitytransform 两个属性

    .motion-common(@duration: @animation-duration-base) {
      animation-duration: @duration;
      animation-fill-mode: both;
    }
    
    .motion-common-leave(@duration: @animation-duration-base) {
      animation-duration: @duration;
      animation-fill-mode: both;
    }
    
    .make-motion(@className, @keyframeName, @duration: @animation-duration-base) {
      .@{className}-enter,
      .@{className}-appear {
        .motion-common(@duration);
    
        animation-play-state: paused;
      }
      .@{className}-leave {
        .motion-common-leave(@duration);
    
        animation-play-state: paused;
      }
      .@{className}-enter.@{className}-enter-active,
      .@{className}-appear.@{className}-appear-active {
        animation-name: ~'@{keyframeName}In';
        animation-play-state: running;
      }
      .@{className}-leave.@{className}-leave-active {
        animation-name: ~'@{keyframeName}Out';
        animation-play-state: running;
        pointer-events: none;
      }
    }
    
    
    .slide-motion(@className, @keyframeName) {
      @name: ~'@{ant-prefix}-@{className}';
      .make-motion(@name, @keyframeName);
      .@{name}-enter,
      .@{name}-appear {
        opacity: 0;
        animation-timing-function: @ease-out-quint;
      }
      .@{name}-leave {
        animation-timing-function: @ease-in-quint;
      }
    }
    
    .slide-motion(slide-up, antSlideUp);
    @keyframes antSlideUpIn {
      0% {
        transform: scaleY(0.8);
        transform-origin: 0% 0%;
        opacity: 0;
      }
      100% {
        transform: scaleY(1);
        transform-origin: 0% 0%;
        opacity: 1;
      }
    }
    
    

    谈谈Select 里面的Option OptionGroup

    首先,Rc-Select 里面的Option 类型是 export type OptionsType = (OptionData | OptionGroupData)[]; 我们来看一下代码片段。

    export interface OptionCoreData {
      key?: Key;
      disabled?: boolean;
      value: Key;
      title?: string;
      className?: string;
      style?: React.CSSProperties;
      label?: React.ReactNode;
      /** @deprecated Only works when use `children` as option data */
      children?: React.ReactNode;
    }
    
    export interface OptionData extends OptionCoreData {
      /** Save for customize data */
      [prop: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any
    }
    
    export interface OptionGroupData {
      key?: Key;
      label?: React.ReactNode;
      options: OptionData[];
      className?: string;
      style?: React.CSSProperties;
    
      /** Save for customize data */
      [prop: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any
    }
    
    export type OptionsType = (OptionData | OptionGroupData)[];
    
    

    同时Select 暴露出了Option, OptGroup 来用于提供Options, 常用于AntD Select. 看一下OptGroup类型定义. 它没有Options 属性。Options 直接来源于children.

    export interface OptGroupProps extends Omit<OptionGroupData, 'options'> {
      children?: React.ReactNode;
    }
    
    export interface OptionGroupFC extends React.FC<OptGroupProps> {
      /** Legacy for check if is a Option Group */
      isSelectOptGroup: boolean;
    }
    
    const OptGroup: OptionGroupFC = () => null;
    OptGroup.isSelectOptGroup = true;
    
    export default OptGroup;
    

    这个是Option的定义,它没有label这个属性,label 直接来源于children.

    export interface OptionProps extends Omit<OptionCoreData, 'label'> {
      children: React.ReactNode;
    
      /** Save for customize data */
      [prop: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any
    }
    
    export interface OptionFC extends React.FC<OptionProps> {
      /** Legacy for check if is a Option Group */
      isSelectOption: boolean;
    }
    
    /** This is a placeholder, not real render in dom */
    const Option: OptionFC = () => null;
    Option.isSelectOption = true;
    
    export default Option;
    

    对于AutoComplete 这个组件,它也是基于Select 来做的,它的Options 是通过Options这个属性来提供的,它的代码片段如下

    export interface DataSourceItemObject {
      value: string;
      text: string;
    }
    export type DataSourceItemType = DataSourceItemObject | React.ReactNode;
    
    export interface AutoCompleteProps
      extends Omit<
        InternalSelectProps<string>,
        'inputIcon' | 'loading' | 'mode' | 'optionLabelProp' | 'labelInValue'
      > {
      dataSource?: DataSourceItemType[];
    }
    

    那么对于分组这种情况,它的Options 应该张这样

    [
        {label:xxx,options:[xxx,xxx,...]},
        {label:xxx,options:[xxx,xxx,...]},
        {label:xxx,options:[xxx,xxx,...]},
        {label:xxx,options:[xxx,xxx,...]},
    ]
    

    对于未分组的情况,它的Options 应该长这样

    [
        {label:xx,value:xxx,key:xxx},
        {label:xx,value:xxx,key:xxx},
        {label:xx,value:xxx,key:xxx},
        {label:xx,value:xxx,key:xxx},
        ...
    ]
    

    在Rc-Select/utils/valueUtil.tsx 里面有这个函数flattenOptions 来解析以上这些数据结构.

    export function flattenOptions(options: SelectOptionsType): FlattenOptionData[] {
      const flattenList: FlattenOptionData[] = [];
    
      function dig(list: SelectOptionsType, isGroupOption: boolean) {
        list.forEach((data) => {
          if (isGroupOption || !('options' in data)) {
            // Option
            flattenList.push({
              key: getKey(data, flattenList.length),
              groupOption: isGroupOption,
              data,
            });
          } else {
            // Option Group
            flattenList.push({
              key: getKey(data, flattenList.length),
              group: true,
              data,
            });
    
            dig(data.options, true);
          }
        });
      }
    
      dig(options, false);
    
      return flattenList;
    }
    
  • 相关阅读:
    JS的Document属性和方法小结
    机器学习笔记——最小二乘法
    c语言中printf()函数中的参数计算顺序
    机器学习笔记——拉格朗日乘子法和KKT条件
    Linux bash笔记
    java.util.ConcurrentModificationException的解决办法
    浅谈对java中传参问题的理解
    机器学习笔记——t分布知识点总结
    机器学习笔记——测试集和验证集的区别
    java中对HashMap遍历的方式
  • 原文地址:https://www.cnblogs.com/kongshu-612/p/14870141.html
Copyright © 2011-2022 走看看