一、Vben框架ApiCascader的一些问题

1,466 阅读3分钟

前言

 

        小伙伴们,大家好,我最近一直在使用vben(Vben Admin)框架,虽然我感觉他封装的不错,但是使用过程中,还是会出现很多很难解决的bug,为了大家在以后的开发中,少走弯路,节省时间,所以我把一些难以解决和不易发现的bug给大家总结出来,大家一起进步。

        今天主要讲讲ApiCascader(动态级联选择器)的问题。主要有几点:

参数

            vben在很多的动态选择器中的参数使用的都是params作为参数来展示(ApiSelect, ApiTreeSelect),例如

举例一个form表单的动态获取

export const addFormSchema: FormSchema[] = [
  {
    field: 'receiveType',
    label: '业务类型',
    component: 'ApiSelect',
    defaultValue: '1',
    componentProps: {
      placeholder: '请选择业务类型',
      api: dictDetailListByCode,
      labelField: 'value',
      valueField: 'code',
      showSearch: true,
      params: { dictType: 'receive_type' },
    },
    required: true,
    colProps: { span: 12 },
  }
]

但是ApiCascader不一样,他是initFetchParams:写法为

export const searchMoreFormSchema: FormSchema[] = [
  {
    field: 'storageIds',
    label: '仓库名称',
    component: 'ApiCascader',
    componentProps: {
      placeholder: '请选择仓库名称',
      api: storageTree,
      labelField: 'storageName',
      valueField: 'id',
      initFetchParams: { serviceType: 5 },
    },
  }
]

无限下级   

删除的load-data,要不然会出现无限级的loading请求,如图。

image.png

如果不删的话,就会出现如图无限循环

image.png

但是实际数据呢只有两层,很尴尬

image.png

箭头的清除

删除load-data之后是不会请求无限下级了,但是每一个上面都有箭头怎么办,很丑啊,而已如果只有两级,没有下级元素的话会造成误导的啊,是个bug,要解决。

image.png

那么我们如何取消这个箭头呢,主要是他的isLeaf属性来决定的。

 interface Option {
    value: string;
    label: string;
    loading?: boolean;
    isLeaf?: boolean;
    children?: Option[];
  }

主要是generatorOptions这个递归函数的方法有问题,iisLeaf一直是false导致的。

image.png

改掉他,咱们自己根据children来做判断。

      function generatorOptions(options: any[]): Option[] {
        const { labelField, valueField, numberToString, childrenField, isLeaf } = props;
        return options.reduce((prev, next: Recordable) => {
          if (next) {
            const value = next[valueField];
            const children = Reflect.get(next, childrenField);
            const item = {
              ...omit(next, [labelField, valueField]),
              label: next[labelField],
              value: numberToString ? `${value}` : value,
              // isLeaf: isLeaf && typeof isLeaf === 'function' ? isLeaf(next) : false,
              isLeaf: children && children.length ? false : true,
            };
            if (children) {
              Reflect.set(item, childrenField, generatorOptions(children));
            }
            prev.push(item);
          }
          return prev;
        }, [] as Option[]);
      }

效果出来了哦耶

image.png

这个问题困扰了我两天时间,其实还有个思路是在数据初始化的时候,把isleaf这个字段就加进去,但是那样就要写函数,就复杂了,代码量直线上升,后端也不愿意增加字段,人家说有children判断去就行了。

回显

如果只赋值那么是显示不出来的,例如这样,那么这样是不行了

setFieldsValue({
        storageIds: data.record.storageIds
});



export const addFormSchema: FormSchema[] = [

 {
    field: 'storageIds',
    label: '仓库名称',
    component: 'ApiCascader',
    componentProps: ({ formModel }) => {
      return {
        placeholder: '请选择仓库名称',
        api: storageTree,
        labelField: 'storageName',
        valueField: 'id',
        initFetchParams: { serviceType: 1 },
      };
    },
    required: true,
    colProps: { span: 12 },
  },
]

会选中 但是不会展示出来,需要增加回显的数据

image.png

setFieldsValue({
        storageIds: data.record.storageIds,
        storageNames: data.record.storageNames,
});



export const addFormSchema: FormSchema[] = [
 {
    field: 'storageIds',
    label: '仓库名称',
    component: 'ApiCascader',
    componentProps: ({ formModel }) => {
      return {
        placeholder: '请选择仓库名称',
        api: storageTree,
        labelField: 'storageName',
        valueField: 'id',
        displayRenderArray: formModel.storageNames,
        initFetchParams: { serviceType: 1 },
      };
    },
    required: true,
    colProps: { span: 12 },
  },
  {
    field: 'storageNames',
    label: '仓库名称',
    component: 'ApiCascader',
    colProps: { span: 12 },
    show: false,
  },
]

这样就可以了,他的bug确实有点多

image.png

以上就是Vben框架中的ApiCascader在项目中遇到的问题,希望对大家有所帮助.