ant design vue 1.7.8版本-动态表单(二)-多层嵌套

背景: 主要是官网给的只有一个Input框的示例,不满足需求,这里就不赘述了~
ant-design 1.7.8版本中,Form组件的内置属性被设计为操作数据的主要方式

需求:外层是可以动态添加,删除的,里层也是可以动态添加,删除的,每层都包含多个属性--

如图所示:

我们把方案分为:

        外层的-添加,删除;
        内层的-添加,删除;

1. 数据仍然是通过v-decorator双向绑定的,v-decorator绑定的外层只拼接了index, 里层拼接了index后又拼接了里层循环的childIndex,来保证唯一的,原因还是由于ant-design的老版本中,form表单的格式是键值对形式,拼接后打印出来如下图所示;
即便是v-for循环的,但不是数组对象的形式,而是Object平铺的形式,如果不通过index,childIndex去拼接,键重名的话就报错了。


{
    eventName-0: '变量1', 
    eventId-0: '变量id1',  
    eventName-1: '变量2', 
    eventId-1: '变量id2',
    dataneeder-0-0: '接收方1',
    dataneeder-0-1: '接收方2',
    dataneeder-1-0: '接收方3',
    dataneeder-1-1: '接收方4',
}

实现方案如下图所示:

接上一张图继续..

2. data里数据定义如下图所示:

3. 外层的添加

4. 外层的删除

跟单层嵌套循环的区别是,多层嵌套在删除后,不仅要把没被删除的父节点的数据赋值,还要把没被删除的子元素的数据赋值,形成新的Object类型键值对的数据,再通过form的setFieldsValue重新赋值给form。

5. 里层的子节点的添加

6. 里层的子节点的删除

这里面都有注释,删除子节点,主要通过取出老的form的值后,通过判断Object的键,这个字符串里有几个短杠 '-',有1个表示是外层的数据,有2个表示是里层的数据,数据格式参照下图:


{
    eventName-0: '变量1', 
    eventId-0: '变量id1',  
    eventName-1: '变量2', 
    eventId-1: '变量id2',
    dataneeder-0-0: '接收方1',
    dataneeder-0-1: '接收方2',
    dataneeder-1-0: '接收方3',
    dataneeder-1-1: '接收方4',
}

(1)判断一个短杠,是外层的数据,不需要动,就把这些数据直接赋值

(2)判断是2个短杠,要判断前面第一个短杠后面的数字跟父节点的Index比较, 如果相等,表示操作的是这个父节点下的数据,处理下index, 把新的处理后的键,赋值。

(3)判断是2个短杠,但跟父节点的index不相等,说明不是操作的这个父元素下的子节点,也不需要动,直接赋值。

(4)把处理后的newFieldsValue重新赋值给form

    delChildNode(parentIndex, childIndex) {
      if (this.keysList[parentIndex].childKeysList.length === 1) {
        this.$message.warning('至少保留一个属性')
        return
      }
      // 删除数组中的数据
      this.keysList[parentIndex].childKeysList.splice(childIndex, 1)
      // 取出表单中的数据
      const oldFieldsValue = this.form.getFieldsValue()
      const newFieldsValue = {}

      // 1. 赋值外层的数据
      for(const objKey in oldFieldsValue) {
        // 把oldFieldsValue里面,对象名为一个'-'的直接赋值到newFieldsValue
        if (objKey.match(/-/g)?.length === 1) {
          // 说明是第一层数据,直接赋值
          newFieldsValue[objKey] = oldFieldsValue[objKey]
        } else {
          // 把oldFieldsValue里面,第一个'-'后面的数字取出来
          // 取出来的数字如果等于parentIndex, 说明操作的是这个里面的数据,要处理下index
          if (objKey.match(/-(\d+)/) && parseInt(objKey.match(/-(\d+)/)[1]) === parentIndex) {
            for (let j = 0; j < this.keysList[parentIndex].childKeysList.length; j++) {
              let oldIndex = j
              if (j >= childIndex) {
                oldIndex = j + 1
              }
              // 重新设置表单值
              for (const key in this.childModelType) {
                newFieldsValue[this.childModelType[key] + parentIndex + '-' + j] = oldFieldsValue[this.childModelType[key]  + parentIndex + '-' + oldIndex]
              }
            }
          } else {
            // 没被操作的直接赋值
            newFieldsValue[objKey] = oldFieldsValue[objKey]
          }
        }
      }
      this.form.setFieldsValue(newFieldsValue)
    },

7. 提交时,也会带校验,这里就是官方的写法了。

    handleSubmit(e) {
      e.preventDefault()
      this.form.validateFields((err, values) => {
        if (err) return
        console.log('submit Values', values)
 
      })
    },

写到最后,我自己觉得里层子节点的删除逻辑有点绕的,如果有其它可以简化代码的思路,欢迎交流评论,一起学习共成长~

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Ant Design Vue 1.7.8 版本中,a-upload 组件可以使用自己封装的接口进行上传文件。你可以在 a-upload 组件的 `customRequest` 属性中指定一个自定义的上传函数,该函数将会代替默认的上传行为。 下面是一个示例代码,演示了如何使用自定义的上传函数上传文件: ```html <template> <a-upload :action="uploadUrl" :custom-request="customUpload" > <a-button icon="upload">上传文件</a-button> </a-upload> </template> <script> import { Upload } from 'ant-design-vue' export default { components: { 'a-upload': Upload }, data () { return { uploadUrl: '/api/upload' } }, methods: { customUpload ({ file, onSuccess, onError, onProgress }) { const xhr = new XMLHttpRequest() xhr.open('POST', this.uploadUrl) xhr.setRequestHeader('Content-Type', 'multipart/form-data') xhr.upload.onprogress = e => { if (e.total > 0) { e.percent = (e.loaded / e.total) * 100 } onProgress({ percent: e.percent }, file) } xhr.onload = e => { if (xhr.status === 200) { onSuccess(JSON.parse(xhr.responseText), file) } else { onError(xhr.statusText, file) } } xhr.onerror = e => { onError(xhr.statusText, file) } const formData = new FormData() formData.append('file', file) xhr.send(formData) } } } </script> ``` 在上述代码中,我们定义了一个 `customUpload` 函数,它接收一个包含上传文件信息和回调函数的对象参数。在这个函数中,我们使用 XMLHttpRequest 发送一个 POST 请求,将文件上传到指定的 URL。在上传过程中,我们监听了 `xhr.upload.onprogress` 事件,以便在文件上传进度发生变化时更新进度条。在上传完成后,根据服务器返回的结果执行相应的回调函数。 最后,我们将 `customUpload` 函数作为 `a-upload` 组件的 `customRequest` 属性的值,以便在上传文件时使用该函数代替默认的上传行为。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值