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
<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> |