vben admin / ant design 的 Form表单获取/设置/清空某个表单项的值 , 使用 setFieldsValue 设置某个字段的时候,表单被清空的解决方案

项目场景:

项目当中用了 vben 框架, vben 是基于 ant design 封装的,项目中有个需求是一个筛选表单,其中筛选条件中通过下拉列表来完成,两个筛选下拉列表有着联动关系


在这里插入图片描述上图是期望的实现结果,客户和工地有着层级关系,当客户切换,对应工地列表会重新加载,而且选中状态清空,其他的选项不变

问题描述

这里在写的时候,一开始的思路是在所属客户的选中事件中清空工地这个字段的值
但是 vue3 + ts 是真的真的不熟悉啊啊啊啊

总之来看看代码叭

    <div class="bg-white mb-2 p-4">
      <BasicForm @register="registerForm" ref="formRef" />
    </div>
//过滤表单相关的代码
  const searchSchemas: FormSchema[] = [
    {
    
    
      field: 'state',
      component: 'Select',
      label: '设备状态',
      colProps: {
    
     span: 4 },
      componentProps: {
    
    
        allowClear: true,
        dictType: 'bu_device_status',
      },
    },
    {
    
    
      field: 'name',
      component: 'Input',
      colProps: {
    
     span: 4 },
      label: '设备名称',
      componentProps: {
    
    
        allowClear: true,
      },
    },
    {
    
    
      field: 'number',
      component: 'Input',
      colProps: {
    
     span: 4 },
      label: '设备编号',
      componentProps: {
    
    
        allowClear: true,
      },
    },
    {
    
    
      field: 'customerId',
      component: 'Select',
      label: '设备所属客户',
      colProps: {
    
     span: 4 },
      componentProps: {
    
    
        allowClear: true,
        onChange: handleCustomerChange, // 这里是自己定义了一个函数,当客户状态改变后执行的
        options: customerOptions, // customerOptions 是在某个方法中获取到了客户列表的数据
      },
    },
    {
    
    
      field: 'siteId',
      component: 'Select',
      label: '设备所属工地',
      colProps: {
    
     span: 4 },
      componentProps: {
    
    
        allowClear: true,
        options: siteOptions,
      }
    }
  ];

下面这里是清空工地下拉列表的相关代码, updateSite 是在 handleCustomerChange 函数中执行的函数
但是这里发现另一个问题 : 用 setFieldsValue 只设置 siteId 这一个字段为空的时候,整个表单全都被清空了
解决方案,在需要设置 siteId 为空之前,先将所有字段当前的值全部都取出来,然后在设置 siteId 的时候再将所有的数据全部再赋值给对应的字段

// 这里定义一个 formRef 对象,是响应式的 ,然后表单对象当中用 ref 来绑定上
const formRef = ref<any>();

// 以下注释掉的全部都是错误的写法,同样踩雷的可以避一避哈哈哈
const updateSite = (customerId: string, siteOptionsArr: Array) => {
    
    
    console.log('try to clear site');
    // console.log(searchSchemas)
    // this.$refs[siteIdRef].resetFields();  // 找不到 refs 啥的
    // searchSchemas.resetFields() //resetFields 不是个函数啥的
    //  this.props.form.resetFields();
    // siteIdRef.current?.resetFields();
    console.log(formRef.value); 

    // formRef.value.setFieldsValue({})
    const searchObj = ref<any>(formRef.value.getFieldsValue()); // 这里是获取当前过滤表单中的所有字段的值
    // console.log(searchObj.value.state)
    // console.log(searchObj.value.name)
    // console.log(searchObj.value.number)
    
    // 将 siteId 字段的值设置为 " " ,但是这里把其他的字段都取出来又再设置回去的原因是 : 发现当只设置 siteId 这一个字段为空的时候,整个表单全都被清空了
    formRef.value.setFieldsValue({
    
    state:searchObj.value.state,name:searchObj.value.name,number:searchObj.value.number,siteId: ''}) 

    //  setTimeout(() => {
    
    
    //   form.setFieldsValue({
    
    
    //     personName: obj.personName,
    //   })
    // }, 0)
    // formRef.value.setFieldsValue(siteId, '')
    // formRef.value.resetFields('siteId');
    // resetSite();
    // formRef.current?.resetFields();
    // searchSchemas.setFieldsValue({username: n})
    // setFieldsValue
    // valiDate.siteId = ''
    // siteIdRef.value.resetFields()
    console.log('真的重置了吗');
    siteOptionsArr.length = 0;

    ConstructionSitList({
    
    
      organizationId: customerId,
    }).then((res) => {
    
    
      console.log('res', res);
      res.list.forEach((element) => {
    
    
        siteOptionsArr.push({
    
     value: element.organizationId, label: element.name });
      });
    });
    console.log(siteOptionsArr);
    // return s/
  };

下面这张图就是一次次试代码 , 就当看看笑话吧 ,哈哈哈 真的是语法都不知道,全靠蒙
在这里插入图片描述


原因分析:

主要有点坑的是 setFieldsValue 来设置某个字段的时候其他的字段会被清空


更加优化一点的方案

在上面的解决思路中,假设表单中有 n 个字段,只有一个需要清空,通过 getFieldsValue 取出来之后,一个个放到 setFieldsValue 中的,但是如果表单中的字段有 20 个呢?

  const searchObj = ref<any>(formRef.value.getFieldsValue()); // 这里是获取当前过滤表单中的所有字段的值
//这里一个个放 emmm 其实有更优雅的方式
  formRef.value.setFieldsValue({
    
    state:searchObj.value.state,
	  name:searchObj.value.name,
	  number:searchObj.value.number,
	  siteId: ''}) 

以下是优化方案

// 这里获取到了用户选中的客户,这时候首先清空工地列表,然后把工地列表查出来
    // 先获取当前表单中的内容
    const searchObj = ref<any>(formRef.value.getFieldsValue());
    // 通过  JSON.parse = > JSON.stringify 来讲对象深拷贝
    const temp = JSON.parse(JSON.stringify(searchObj.value));
    // 如果当前的 siteId 不为空,设置成空的
    if (temp.siteId !== undefined) {
    
    
      temp.siteId = '';
    }
    // 表单中的字段只有 siteId 被清空,剩下的字段还在 temp 当中,再赋值给表单 
    //(因为执行 setFieldsValue 之后,会导致除了设置的字段以外的整个表单清空)
    formRef.value.setFieldsValue({
    
     ...temp });

猜你喜欢

转载自blog.csdn.net/YZRHANYU/article/details/129442079
今日推荐