描述
有些时候会碰到一些使用到动态表单的需求,可以动态添加和删除数据,并且对用户输入的数据进行校验。如下图所示:
实现思路
对于这种需求,可以用table结合form来实现,在外层弄个form,然后form里面嵌套一个table,直接看代码
<template>
<div class="container">
<a-row>
<h1>动态表单demo</h1>
</a-row>
<a-form ref="formRef" :model="formData" auto-label-width :rules="rules">
<a-table :data="formData.data" :pagination="false">
<template #columns>
<!-- 姓名 -->
<a-table-column title="姓名" align="center">
<template #cell="{ rowIndex, record }">
<a-form-item :field="`data.${rowIndex}.name`" :rules="rules.name">
<a-input v-model="record.name" />
</a-form-item>
</template>
</a-table-column>
<!-- 年龄 -->
<a-table-column title="年龄" align="center">
<template #cell="{ rowIndex, record }">
<a-form-item :field="`data.${rowIndex}.age`" :rules="rules.age">
<a-input v-model="record.age" />
</a-form-item>
</template>
</a-table-column>
<!-- 操作 -->
<a-table-column :width="200" align="center">
<template #title>
<a-button type="outline" @click="add">
<template #icon>
<icon-plus />
</template>
添加
</a-button>
</template>
<template #cell="{ record, rowIndex }">
<a-space>
<a-button type="primary" @click="remove(record, rowIndex)">
<template #icon>
<icon-delete />
</template>
删除
</a-button>
</a-space>
</template>
</a-table-column>
</template>
</a-table>
</a-form>
<a-row>
<a-col :span="6" :offset="6">
<a-button type="primary" @click="submitForm">提交</a-button>
</a-col>
</a-row>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue';
import { Message } from '@arco-design/web-vue';
const formRef = ref();
const genereataData = () => {
return {
name: undefined,
age: undefined,
};
};
const formData = ref({
data: [genereataData()],
});
const rules = reactive({
name: [
{ required: true, message: '不能为空', trigger: 'blur' },
{ maxLength: 64, message: '长度不能超过64位', trigger: 'blur' },
],
age: [{ required: true, message: '不能为空', trigger: 'blur' }],
});
/**
* 添加一条数据
*/
const add = () => {
formData.value.data.push(genereataData());
};
/**
* 删除数据
* @param record 点击那一行的数据
* @param rowIndex 行索引
*/
const remove = (record: any, rowIndex: any) => {
formData.value.data.splice(rowIndex, 1);
};
/**
* 备用
* 判读元素是否为空
* @param obj 元素
*/
const validatedObjIsNull = (obj: any) => {
return obj === null || obj === '' || obj === undefined;
};
const submitForm = async () => {
const validated = await formRef.value.validate();
if (validated) {
Message.warning('验证失败');
return;
}
Message.success('验证成功');
// do something
};
</script>
<style lang="less" scoped>
.container {
padding: 15px 20px 0;
:deep(.arco-card) {
border-radius: 4px;
}
}
</style>