- 实现功能
1. 可以添加行、删除行
2. 可以实现输入时,校验输入内容,在点击确定时,校验整体格式
注意:
1.name属性是:name="['dataSource', index, 'name']",整个form绑定的是formData,table绑定的是formData.dataSource。
2. v-model:value="record['name']" ,record是这行数据
<a-form ref="tableFormRef" :model="formData" :label-col="{ style: { width: '100px' } }" :wrapper-col="{ span: 0 }"
autocomplete="off">
<a-form-item label="通知名称" :rules="rulesCheck.warnName" name="warnName">
<a-input v-model:value="formData.warnName"></a-input>
</a-form-item>
<a-form-item label="通知方式" :rules="rulesCheck.value1" name="value1">
<a-checkbox-group v-model:value="formData.value1" :options="plainOptions">
</a-checkbox-group>
</a-form-item>
<a-form-item label="添加一行">
<a-button size="small" @click="addRow">
<template #icon>
<PlusOutlined />
</template>
</a-button>
</a-form-item>
<a-table class="ant-table-striped" bordered :dataSource="formData.dataSource" :columns="tableColumns"
:pagination="false">
<template #bodyCell="{ column, text, record, index }">
<template v-if="column.dataIndex == 'name'">
<a-form-item :name="['dataSource', index, 'name']"
:rules="rulesCheck.name">
<a-input v-model:value="record['name']"></a-input>
</a-form-item>
</template>
<template v-if="column.dataIndex == 'iphone'">
<a-form-item :name="['dataSource', index, 'iphone']"
:rules="rulesCheck.iphone">
<a-input v-model:value="record[column.dataIndex]"></a-input>
</a-form-item>
</template>
<template v-if="column.dataIndex == 'email'">
<a-form-item v-model:value="record[column.dataIndex]"
:rules="rulesCheck.email" :name="['dataSource', index, 'email']">
<a-input v-model:value="record[column.dataIndex]"></a-input>
</a-form-item>
</template>
<template v-if="column.dataIndex == 'operation'">
<a-button size="small" @click="delRow(index)">
<template #icon>
<CloseOutlined />
</template>
</a-button>
</template>
</template>
</a-table>
<a-button @click="ok">确定</a-button>
<a-button @click="cancel">取消</a-button>
</a-form>
</div>
</template>
- fromData格式
注意:formData里面dataSource里面是表单校验,其他是其他表单组件
let formData: any = ref({
dataSource: [{ name: "", iphone: "", email: "" }],
warnName: "",
value1: ["10", "01"],
warnProbability: ["", ""],
});
function addRow() {
formData.value.dataSource.push({ name: "", iphone: "", email: "" });
}
function delRow(index) {
formData.value.dataSource.splice(index, 1);
}
//点击确定时调用组件方法即可。tableFormRef.value.validate()
//这里有个缺陷,本来想使用validateFields校验部分对应字段,如选择邮箱,就校验姓名和邮箱
tableFormRef.value.validateFields(['name','email'])
但是不生效,我理解的是该方法会校验formData.dataSource,
它不会校验formData.dataSource里面的name和email,
所有我采用折中的方案,如果只选择了其中一种,通过遍历formData.dataSource的值,进行一个弹窗展示。
完整代码
<template>
<div style="width: 800px;padding: 100px;">
<a-form ref="tableFormRef" :model="formData" :label-col="{ style: { width: '100px' } }" :wrapper-col="{ span: 0 }"
autocomplete="off">
<a-form-item label="通知名称" :rules="rulesCheck.warnName" name="warnName">
<a-input v-model:value="formData.warnName"></a-input>
</a-form-item>
<a-form-item label="通知方式" :rules="rulesCheck.value1" name="value1">
<a-checkbox-group v-model:value="formData.value1" :options="plainOptions">
</a-checkbox-group>
</a-form-item>
<a-form-item label="添加一行">
<a-button size="small" @click="addRow">
<template #icon>
<PlusOutlined />
</template>
</a-button>
</a-form-item>
<a-table class="ant-table-striped" bordered :dataSource="formData.dataSource" :columns="tableColumns"
:pagination="false">
<template #bodyCell="{ column, text, record, index }">
<template v-if="column.dataIndex == 'name'">
<a-form-item :name="['dataSource', index, 'name']"
:rules="rulesCheck.name">
<a-input v-model:value="record['name']"></a-input>
</a-form-item>
</template>
<template v-if="column.dataIndex == 'iphone'">
<a-form-item :name="['dataSource', index, 'iphone']"
:rules="rulesCheck.iphone">
<a-input v-model:value="record[column.dataIndex]"></a-input>
</a-form-item>
</template>
<template v-if="column.dataIndex == 'email'">
<a-form-item v-model:value="record[column.dataIndex]"
:rules="rulesCheck.email" :name="['dataSource', index, 'email']">
<a-input v-model:value="record[column.dataIndex]"></a-input>
</a-form-item>
</template>
<template v-if="column.dataIndex == 'operation'">
<a-button size="small" @click="delRow(index)">
<template #icon>
<CloseOutlined />
</template>
</a-button>
</template>
</template>
</a-table>
<a-button @click="ok">确定</a-button>
<a-button @click="cancel">取消</a-button>
</a-form>
</div>
</template>
<script setup lang="ts">
import { ref, } from "vue";
import { modleRuleColumns } from "./model.data";
import { PlusOutlined, CloseOutlined } from "@ant-design/icons-vue";
import { rulesCheck } from "@/utils/rules";
let tableColumns = ref(modleRuleColumns);
// 表单校验
const tableFormRef = ref();
const plainOptions = [
{ label: "短信", value: "10" },
{ label: "邮箱", value: "01" },
];
let formData: any = ref({
dataSource: [{ name: "", iphone: "", email: "" }],
warnName: "",
value1: ["10", "01"],
warnProbability: ["", ""],
});
function addRow() {
formData.value.dataSource.push({ name: "", iphone: "", email: "" });
}
function delRow(index) {
formData.value.dataSource.splice(index, 1);
}
async function ok() {
if (formData.value.dataSource.length == 0) {
alert("至少添加一条数据");
return;
}
let checkStr = formData.value.value1.join(" ");
if (!checkStr) {
alert("请至少选择一种通知方式");
return;
}
// 全校验 全选
if (checkStr.indexOf(" ") > -1) {
tableFormRef.value.validate().then(() => {
//调用接口执行下一步
});
return;
}
// 短信校验 邮箱校验
if (checkStr == "10" || checkStr == "01") {
// 无法校验指定form
// tableFormRef.value.validateFields(["email", "name"])
console.log("getErrorList()", getErrorList());
if (getErrorList()) {
console.log('getErrorList()',getErrorList());
alert('提示')
return;
}
//校验通过后,执行方法
}
}
function getErrorList() {
// 11 邮箱和手机号 只考虑:01邮箱 10短信
// getPushType()
let filterFlag: string[] = [];
if (getPushType() == "01") {
filterFlag = ["email", "name"];
}
if (getPushType() == "10") {
filterFlag = ["iphone", "name"];
}
let result = [] as any;
formData.value.dataSource.map((el, idx) => {
if (!el[filterFlag[0]] || !el[filterFlag[1]]) {
el.index = idx + 1;
result.push(el);
}
});
if (result.length > 0) {
let info = "";
result.forEach((el) => {
info += `第${el.index}行需要填写${!el.name ? "姓名," : ""}${!el.iphone ? "手机号," : ""}${!el.email ? "邮箱" : ""}</br>`;
});
return info;
}
}
function cancel(){
}
function getPushType() {
let checkStr = formData.value.value1.join(" ");
if (checkStr && checkStr.indexOf(" ") > -1) {
return "11";
}
return checkStr;
}
</script>
export const modleRuleColumns = [
{
title: '序号',
dataIndex: 'index',
width: 80,
customRender: ({ index }) => { return index + 1 }
},
{
title: '姓名',
dataIndex: 'name',
width: 150,
},
{
title: '手机号',
dataIndex: 'iphone',
width: 150,
},
{
title: '邮箱',
dataIndex: 'email',
width: 150,
},
{
title: '操作',
dataIndex: 'operation',
width: 80,
align: "center"
},
]