Antd组件库中绑定form表单,包含upload组件,报错You cannot set a form field before rendering a field associated with t

项目场景:

昨天公司让写一个增删改查页面,使用的是Antd组件库,其中包含图片的上传组件,按照form表单文档里,抄写了示例,unpload组件可以使用v-decorator绑定fileList,但公司要求传入后端的是上传后的url地址,当然也可以使用这种方式直接绑定fileList,在提交表单后再重新将拿到的url地址再传递给后端。

 <a-upload
        v-decorator="[
          'upload',
          {
            valuePropName: 'fileList',
            getValueFromEvent: normFile,
          },
        ]"
        name="logo"
        action="/upload.do"
        list-type="picture"
      >
        <a-button> <a-icon type="upload" /> Click to upload </a-button>
      </a-upload>

不过一开始看组件时,直接使用了上传图片并在列表中显示缩略图的a-upload组件实例代码,也就有了后面我遇见这个bug的开始…

上传图片可插件缩略图


控制台报错:

当我将上图示例代码直接粘贴至form表单中,因为打算在上传成功后handleChange方法里,直接将后端返回的url传递给我的imgUrl字段,但一直报错如下:

Warning: You cannot set a form field before rendering a field associated with the value. You can use getFieldDecorator(id, options) instead v-decorator="[id, options]" to register it before render.
警告:在呈现与该值关联的字段之前,不能设置表单字段。你可以使用getFieldDecorator(id, options)代替v-decorator="[id, options]"来在渲染前注册它。


原因分析:

查找了很久的原因才发现,使用Form表单时使用表单setFieldsValue时,有的字段设置了,但Form里不存在这个field。也就是说我赋值的时候,根本不存在imgUrl字段,从log打印果然发现字段结果是undefined,其实在antd的form表单创建form对象时,是通过 this.$form.createForm(),并搭配着 v-decorator,才使得注册了对象里的每个字段,而我在upload字段中并没有使用 v-decorator,所以导致了报错。


解决方案:

解决方案呢有两种
第一种可以直接在Dom节点中直接创建该字段

mounted() {
    this.form.getFieldDecorator('imgurl', {
      initialValue: '',
      rules: [{ required: true, message: '请输入封面图片地址!' }],
    });
  },

第二种方式呢,也可以直接在a-upload组件中添加一个隐藏的input框

<!-- 添加隐藏的input输入框,v-decorator来关联imgurl字段 -->
<a-input type="hidden" v-decorator="[ 'imgurl', {initialValue: '', rules: [{ required: true, message: '请输入封面图片地址!' }] }]" />

以上两种方式任选,都可以实现在form中设置imgUrl字段,最后再在上传文件成功时,重新赋值imgUrl,在提交时form表单就可以看到这个字段及值啦。

// 文件上传
    handleChange (info) {
      const { file } = info;
      // 判断文件状态
      switch (file.status)
      {
        case 'uploading':
          // 上传中,不做处理
          break;
        case 'done':
          // 上传成功
          if (file.response && file.response.code === 200)
          {
            // 确保在使用setFieldsValue之前,表单字段已经被注册
            this.form.setFieldsValue({
              imgurl: file.response.data.url,
            });
            this.$message.success('上传成功');
          } else
          {
            // 上传失败,但服务器返回了响应
            this.$message.error('上传失败,请重试');
          }
          break;
        case 'error':
          // 上传失败,没有从服务器得到响应
          this.$message.error('上传失败,请检查网络连接');
          break;
        default:
          // 其他状态,不做处理
          break;
      }
      this.fileList = info.fileList;
    },

当然,也可以直接在提交时通过上传文件的this.fileList 取值上传,只不过那样的话,校验规则还得重新写相关代码,所以还是不用这种方式了。

以上均为个人的菜鸟总结,记录自己免得下次踩坑还是不知道解决方法吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值