You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
5.6 KiB
196 lines
5.6 KiB
|
4 months ago
|
<template>
|
||
|
|
<div class="form-table-demo">
|
||
|
|
<el-form
|
||
|
|
ref="formRef"
|
||
|
|
:model="form"
|
||
|
|
:rules="formRules"
|
||
|
|
label-width="100px"
|
||
|
|
>
|
||
|
|
<!-- 其他表单字段(可选) -->
|
||
|
|
<el-form-item label="表单名称" prop="name">
|
||
|
|
<el-input v-model="form.name"></el-input>
|
||
|
|
</el-form-item>
|
||
|
|
|
||
|
|
<!-- 表格嵌套:绑定到form的tableData数组 -->
|
||
|
|
<el-form-item label="日期列表" prop="tableData">
|
||
|
|
<el-table
|
||
|
|
:data="form.tableData"
|
||
|
|
border
|
||
|
|
style="width: 100%; margin-top: 10px"
|
||
|
|
@row-click="handleRowClick"
|
||
|
|
>
|
||
|
|
<el-table-column label="序号" type="index" width="60"></el-table-column>
|
||
|
|
<el-table-column label="日期" prop="date">
|
||
|
|
<template #default="scope">
|
||
|
|
<!-- 表格行内的日期选择器,绑定到行数据的date字段 -->
|
||
|
|
<el-date-picker
|
||
|
|
v-model="scope.row.date"
|
||
|
|
type="date"
|
||
|
|
placeholder="选择日期"
|
||
|
|
style="width: 100%"
|
||
|
|
@change="() => validateSingleRow(scope.row)"
|
||
|
|
></el-date-picker>
|
||
|
|
</template>
|
||
|
|
</el-table-column>
|
||
|
|
<el-table-column label="操作" width="100">
|
||
|
|
<template #default="scope">
|
||
|
|
<el-button
|
||
|
|
type="text"
|
||
|
|
icon="el-icon-delete"
|
||
|
|
@click="handleDeleteRow(scope.$index)"
|
||
|
|
>
|
||
|
|
删除
|
||
|
|
</el-button>
|
||
|
|
</template>
|
||
|
|
</el-table-column>
|
||
|
|
</el-table>
|
||
|
|
|
||
|
|
<!-- 添加行按钮 -->
|
||
|
|
<el-button
|
||
|
|
type="primary"
|
||
|
|
icon="el-icon-plus"
|
||
|
|
size="mini"
|
||
|
|
style="margin-top: 10px"
|
||
|
|
@click="handleAddRow"
|
||
|
|
>
|
||
|
|
添加行
|
||
|
|
</el-button>
|
||
|
|
</el-form-item>
|
||
|
|
|
||
|
|
<!-- 提交按钮 -->
|
||
|
|
<el-form-item>
|
||
|
|
<el-button type="primary" @click="handleSubmit">提交</el-button>
|
||
|
|
<el-button @click="handleReset">重置</el-button>
|
||
|
|
</el-form-item>
|
||
|
|
</el-form>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
export default {
|
||
|
|
name: "FormTableDateCheck",
|
||
|
|
data() {
|
||
|
|
// 自定义校验:表格行内日期必填
|
||
|
|
const validateDateRequired = (rule, value, callback) => {
|
||
|
|
// 遍历表格数据,检查每一行的date是否为空
|
||
|
|
const hasEmpty = value.some((row) => !row.date);
|
||
|
|
if (hasEmpty) {
|
||
|
|
callback(new Error("请填写所有行的日期"));
|
||
|
|
} else {
|
||
|
|
// 先清空重复日期的错误提示(避免残留)
|
||
|
|
this.$refs.formRef.clearValidate("tableData");
|
||
|
|
callback();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 自定义校验:表格日期是否重复(核心:只提示一次)
|
||
|
|
const validateDateDuplicate = (rule, value, callback) => {
|
||
|
|
if (value.length === 0) {
|
||
|
|
callback();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 提取所有非空日期,转换为字符串(统一格式)
|
||
|
|
const dateList = value
|
||
|
|
.map((row) => (row.date ? this.formatDate(row.date) : ""))
|
||
|
|
.filter((date) => date);
|
||
|
|
|
||
|
|
// 判断是否有重复
|
||
|
|
const isDuplicate = dateList.length !== new Set(dateList).size;
|
||
|
|
if (isDuplicate) {
|
||
|
|
callback(new Error("表格中存在重复的日期,请修改"));
|
||
|
|
} else {
|
||
|
|
callback();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
return {
|
||
|
|
// 表单数据
|
||
|
|
form: {
|
||
|
|
name: "", // 其他表单字段
|
||
|
|
tableData: [
|
||
|
|
// 初始表格行数据
|
||
|
|
{ date: "" },
|
||
|
|
],
|
||
|
|
},
|
||
|
|
|
||
|
|
// 表单校验规则
|
||
|
|
formRules: {
|
||
|
|
name: [
|
||
|
|
{ required: true, message: "请输入表单名称", trigger: "blur" },
|
||
|
|
],
|
||
|
|
tableData: [
|
||
|
|
{ required: true, validator: validateDateRequired, trigger: "change" },
|
||
|
|
{ validator: validateDateDuplicate, trigger: "change" },
|
||
|
|
],
|
||
|
|
},
|
||
|
|
};
|
||
|
|
},
|
||
|
|
methods: {
|
||
|
|
// 格式化日期为字符串(解决Date对象比较的问题)
|
||
|
|
formatDate(date) {
|
||
|
|
if (typeof date === "string") return date;
|
||
|
|
const year = date.getFullYear();
|
||
|
|
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||
|
|
const day = String(date.getDate()).padStart(2, "0");
|
||
|
|
return `${year}-${month}-${day}`;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 校验单行数据(可选:实时校验)
|
||
|
|
validateSingleRow(row) {
|
||
|
|
this.$refs.formRef.validateField("tableData");
|
||
|
|
},
|
||
|
|
|
||
|
|
// 添加表格行
|
||
|
|
handleAddRow() {
|
||
|
|
this.form.tableData.push({ date: "" });
|
||
|
|
// 新增行后触发校验(避免空行影响)
|
||
|
|
this.$nextTick(() => {
|
||
|
|
this.$refs.formRef.validateField("tableData");
|
||
|
|
});
|
||
|
|
},
|
||
|
|
|
||
|
|
// 删除表格行
|
||
|
|
handleDeleteRow(index) {
|
||
|
|
this.form.tableData.splice(index, 1);
|
||
|
|
// 删除行后触发校验
|
||
|
|
this.$nextTick(() => {
|
||
|
|
this.$refs.formRef.validateField("tableData");
|
||
|
|
});
|
||
|
|
},
|
||
|
|
|
||
|
|
// 表单提交
|
||
|
|
handleSubmit() {
|
||
|
|
this.$refs.formRef.validate((valid) => {
|
||
|
|
if (valid) {
|
||
|
|
// 校验通过,执行提交逻辑
|
||
|
|
alert("表单校验通过,可提交数据");
|
||
|
|
console.log("表单数据:", this.form);
|
||
|
|
} else {
|
||
|
|
// 校验失败,ElementUI会自动显示错误提示
|
||
|
|
console.log("表单校验失败");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
});
|
||
|
|
},
|
||
|
|
|
||
|
|
// 表单重置
|
||
|
|
handleReset() {
|
||
|
|
this.$refs.formRef.resetFields();
|
||
|
|
// 重置表格数据为初始状态
|
||
|
|
this.form.tableData = [{ date: "" }];
|
||
|
|
},
|
||
|
|
|
||
|
|
// 表格行点击(可选:自定义逻辑)
|
||
|
|
handleRowClick(row) {
|
||
|
|
console.log("点击行数据:", row);
|
||
|
|
},
|
||
|
|
},
|
||
|
|
};
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style scoped>
|
||
|
|
.form-table-demo {
|
||
|
|
padding: 20px;
|
||
|
|
}
|
||
|
|
</style>
|