ant-design动态增减 form 表单

业务场景: 通过点击增加按钮,可以动态增加一列表单项,点击删除,删除此项

但是 最后的提交按钮是在父页面,点击提交时,需要拿到子组件 form 表单数据, 一般的,父组件想要拿到子组件的数据,需要给子组件设置一个 ref, 不过这里的子组件是动态的,ref 不能动态赋值
看了 antdesign 中 form 表单里面的动态增减项,是用一个 form 包裹,里面循环

根据这个方法,结合自己的组件,修改了一下写法

子组件 order.vue
验证的核心就是 :name 这里的参数, 如果是单个表单, name=“当前项的名称”
列表中,需要告知是第几行的数据 [‘数组名’, ‘index’, ‘参数名’] list[0].name 这样就能验证了
<template>
  <div class="order">
    <p>序号: {{ order + 1 }}</p>
    <a-button type="primary" @click="deleteTable">删除</a-button>
    <a-form-item
      label="名称"
      :name="['formList', order, 'name']" // 注意这里的name组成, 第一项是这个data数组列表的数据名称, 第二项是数组列表的index, 第三项是当前项表单的名称
      :rules="rules.name"
    >
      <a-input v-model:value="form.name" /> // v-model我项目这里要加:value,根据你项目里的写法
    </a-form-item>
    <a-form-item
      label="年龄"
      :name="['formList', order, 'age']"
      :rules="rules.age"
    >
      <a-input-number v-model:value="form.age" style="width: 100%" />
    </a-form-item>
    <a-form-item
      label="日期"
      :name="['formList', order, 'date']"
      :rules="rules.date"
    >
      <a-date-picker
        v-model:value="form.date"
        value-format="YYYY-MM-DD"
        style="width: 100%"
      />
    </a-form-item>
  </div>
</template>

<script>
import { ref } from "vue";
export default {
  props: {
    order: {
      // 表单序号
      type: Number,
      default: 0,
    },
    form: {
      // 每一项表单
      type: Object,
      default: () => {},
    },
  },
  setup(props, { emit }) {
    const formRef = ref(null);
    const rules = {
      name: [{ required: true, message: "请输入名称", trigger: "blur" }],
      age: [{ required: true, message: "请输入年龄", trigger: "blur" }],
      date: [{ required: true, message: "请选择日期", trigger: "change" }],
    };

    const deleteTable = () => {
      emit("deleteTable", props.order);
    };
    return {
      deleteTable,
      rules,
      formRef,
    };
  },
};
</script>

<style>
.order {
  margin-top: 15px;
  background: wheat;
  padding: 12px;
}
</style>
父组件 index.vue
<template>
  <div>
    <h3>动态增减表单</h3>
    <a-button type="primary" @click="addTable">新增</a-button>
    <a-form
      ref="formRef"
      name="dynamic_form_item"
      :model="info"
      :label-col="{ span: 5 }"
      :wrapper-col="{ span: 10 }"
    >
      <order
        @deleteTable="deleteTable"
        :order="i"
        v-for="(item, i) in formList"
        :form="item"
      />
    </a-form>
    <div class="submit" v-show="formList.length">
      <a-button type="primary" @click="submit">提交</a-button>
    </div>
  </div>
</template>

<script>
import { reactive, ref, toRefs } from "vue";
import Order from "./components/order.vue";
import { message } from "ant-design-vue";
export default {
  components: {
    Order,
  },
  setup() {
    const info = reactive({
      formList: [], // 这个formList就是子组件里name的第一项,
    });
    const formRef = ref(null);
    const addTable = () => {
      info.formList.push({
        name: "",
        age: null,
        date: "",
      });
    };
    const deleteTable = (key) => {
      info.formList.splice(key, 1);
    };
    const submit = () => {
      formRef.value.validateFields().then(() => {
        console.log(info.formList);
        message.success("success");
      });
    };
    return {
      info,
      ...toRefs(info),
      addTable,
      deleteTable,
      submit,
      formRef,
    };
  },
};
</script>

<style>
.submit {
  text-align: right;
  margin-top: 20px;
}
</style>
这个在可编辑表格里也是一样的用法
注意 form-item 中 name 的值就可以了

最后在提交时,调用 form 验证方法,就能实现 form 表单的动态增减了
posted @ 2023-02-12 20:35  潇湘羽西  阅读(1329)  评论(0编辑  收藏  举报