Ant design vue 动态表单

Ant design vue 动态表单

1、官方示例

首先我们先看一下官网给出的示例:

点击Add filed 会增加一个新的input输入框
在这里插入图片描述
点击删除的时候可以删除该行input框
下面给出官网的demo示例:

<template>
  <a-form :form="form" @submit="handleSubmit">
    <a-form-item
      v-for="(k, index) in form.getFieldValue('keys')"
      :key="k"
      v-bind="index === 0 ? formItemLayout : formItemLayoutWithOutLabel"
      :label="index === 0 ? 'Passengers' : ''"
      :required="false"
    >
      <a-input
        v-decorator="[
          `names[${k}]`,
          {
            validateTrigger: ['change', 'blur'],
            rules: [
              {
                required: true,
                whitespace: true,
                message: 'Please input passenger\'s name or delete this field.',
              },
            ],
          },
        ]"
        placeholder="passenger name"
        style="width: 60%; margin-right: 8px"
      />
      <a-icon
        v-if="form.getFieldValue('keys').length > 1"
        class="dynamic-delete-button"
        type="minus-circle-o"
        :disabled="form.getFieldValue('keys').length === 1"
        @click="() => remove(k)"
      />
    </a-form-item>
    <a-form-item v-bind="formItemLayoutWithOutLabel">
      <a-button type="dashed" style="width: 60%" @click="add">
        <a-icon type="plus" /> Add field
      </a-button>
    </a-form-item>
    <a-form-item v-bind="formItemLayoutWithOutLabel">
      <a-button type="primary" html-type="submit">
        Submit
      </a-button>
    </a-form-item>
  </a-form>
</template>

<script>
let id = 0;
export default {
  data() {
    return {
      formItemLayout: {
        labelCol: {
          xs: { span: 24 },
          sm: { span: 4 },
        },
        wrapperCol: {
          xs: { span: 24 },
          sm: { span: 20 },
        },
      },
      formItemLayoutWithOutLabel: {
        wrapperCol: {
          xs: { span: 24, offset: 0 },
          sm: { span: 20, offset: 4 },
        },
      },
    };
  },
  beforeCreate() {
    this.form = this.$form.createForm(this, { name: 'dynamic_form_item' });
    this.form.getFieldDecorator('keys', { initialValue: [], preserve: true });
  },
  methods: {
    remove(k) {
      const { form } = this;
      // can use data-binding to get
      const keys = form.getFieldValue('keys');
      // We need at least one passenger
      if (keys.length === 1) {
        return;
      }

      // can use data-binding to set
      form.setFieldsValue({
        keys: keys.filter(key => key !== k),
      });
    },

    add() {
      const { form } = this;
      // can use data-binding to get
      const keys = form.getFieldValue('keys');
      const nextKeys = keys.concat(id++);
      // can use data-binding to set
      // important! notify form to detect changes
      form.setFieldsValue({
        keys: nextKeys,
      });
    },

    handleSubmit(e) {
      e.preventDefault();
      this.form.validateFields((err, values) => {
        if (!err) {
          const { keys, names } = values;
          console.log('Received values of form: ', values);
          console.log(
            'Merged values:',
            keys.map(key => names[key]),
          );
        }
      });
    },
  },
};
</script>
<style>
.dynamic-delete-button {
  cursor: pointer;
  position: relative;
  top: 4px;
  font-size: 24px;
  color: #999;
  transition: all 0.3s;
}
.dynamic-delete-button:hover {
  color: #777;
}
.dynamic-delete-button[disabled] {
  cursor: not-allowed;
  opacity: 0.5;
}
</style>

2、重点解析

我们分析官网给出的demo,可以知道整个表单的重点构成在于:
在这里插入图片描述
遍历form表单中keys数组,为form-item赋予不同的key,紧接着生成a-input
所以我们也可以推测出,进行动态的动态增加、减少表单项的关键在于操作keys数组。
我们在通过v-decorator为input绑定数据源时,需要使用names[${k}],如下图所示:
在这里插入图片描述
我们在表单构建之前使用生命周期beforeCreate,首先使用createForm创建表单,然后为表单的keys设置初始值为空数组,并且设置keys是保留项。
在这里插入图片描述

在remove和add方法中主要是操作keys数组的变化,然后通过setFieldsValue设置keys的值。
例如:
form.setFieldsValue({
keys: keys.filter(key => key !== k),
});
到这里官网示例可以满足我们大部分需求,但是在使用接口数据动态的加载表单的时候,因为异步问题会存在一些问题。下面我将会为大家解答这些问题。

3、异步的动态表单

废话不多说先上代码:

<template>
  <a-form
    :form="form"
  >
    <template v-if="show">
      <a-form-item
        v-for="(key, index) in form.getFieldValue('keys')"
        :key="key"
        :label="`${index+1}WHY`"
      >
        <a-input
          v-decorator="[
            `names[${key}]`, {
            }]"
        />
      </a-form-item>
      <a-form-item
        :label="'test'"
      >
        <a-input
          v-decorator="[
            `test`, {
            }]"
        />
      </a-form-item>
    </template>
  </a-form>
</template>

</template>
<script>

export default {
  data () {
    return {
      show: false,
    };
  },
  beforeCreate () {
    this.form = this.$form.createForm(this);
    // 通过setTimeout模拟网络请求
    setTimeout((res) => {
      this.form.getFieldDecorator('keys', { initialValue: res.keys, preserve: true });
      this.show = true;
      this.$nextTick(() => {
        this.form.setFieldsValue(res);
      });
    }, 2000, { keys: [0, 1, 2, 3], names: ['窗前明月光', '疑似地上霜', '举头望明月', '低头思故乡'], test: 'test' });
  },
};
</script>

我们使用setTimeout模拟网络请求,来实现模仿异步请求生成动态表单。
其中需要注意的是
1、我们需要先将表单设置为隐藏状态,在接口返回数据之后,设置表单为显示状态。
2、我们使用setFieldsValue设置表单的显示值时,需要使用nextTick,否则无法设置成功。
3、另外需要注意的一点时,keys数组必须从0开始。
运行结果:
在这里插入图片描述
注解:
1、如果你在使用的过程中遇到了,第一个input框无法赋值的时候,可以尝试单独设置第一个input框的v-decorator的names[0]改为下标非0的值。
例如:this.form.setFieldsValue({ ‘names[11]’: res[0].whyDescription });
2、如果你在生命周期中设置了names的初始值,例如:
this.form.getFieldDecorator(‘names’, { initialValue: [], preserve: false });
那么每次刷新的表单的时候都会把默认值设置成空,如果不需要此功能,请删除此行代码。

参考文档:https://www.jianshu.com/p/a22604f88f3b

Ant Design Vue 是一个非常受欢迎的 UI 组件库,它提供了丰富的表单组件,包括输入框、下拉选择框等等。要实现动态添加表单必填校验,可以按照以下步骤进行操作: 1. 首先,引入 Ant Design Vue 的 Form 组件和相应的验证规则模块,例如 `required` 必填规则。 2. 在 Vue 的 data 中定义一个表单对象,包含需要动态添加的表单控件的值。 3. 在模板中使用 Ant Design Vue 的 Form 组件,并使用 v-model 指令将表单对象和控件的值进行绑定。 4. 使用 v-for 指令遍历需要动态添加的表单控件,通过一个数组来提供控件的模板。 5. 在表单控件的模板中,使用 :rules 属性绑定验证规则,例如 `:rules="[{ required: true, message: '该字段为必填项' }]` 6. 在模板中提供一个按钮或其他交互方式,用来触发动态添加表单控件的操作。 7. 当点击按钮时,通过修改表单对象的属性或者添加新的属性,实现动态添加表单控件。 8. 提交表单时,通过调用 validate 方法对表单进行校验,这会触发相关的验证规则。 9. 根据校验结果,可以在模板中展示错误信息或者处理其他逻辑。 需要注意的是,动态添加表单必填校验时,需要在动态添加表单控件的同时,将相应的验证规则也添加到表单对象中。另外,为了方便校验和错误信息的展示,建议使用对应的验证规则模块和提示文本。 这样,通过上述步骤,就可以实现 Ant Design Vue 动态添加表单必填校验了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值