如何检测Vue表单输入行数组中是否存在与此前行完全重复的冗余行
实现方案说明
你的需求可以通过Laravel内置的distinct校验规则完美实现,无需额外开发自定义校验逻辑,具体实现流程如下:
第一步:前端提交数据格式调整
提交表单时需要将每行的四个字段拼接为结构统一的数组传给后端,参考提交逻辑示例:
// 前端Vue提交逻辑示例 submit() { const rows = [] // 遍历所有表单行,组装为结构化数组 for (let i = 0; i < this.items.length; i++) { rows.push({ date: document.getElementById(`date-${i}`).value, project_id: document.getElementById(`project_id-${i}`).value, hours: document.getElementById(`hours-${i}`).value, description: document.getElementById(`description-${i}`).value }) } // 提交前可加前端前置校验优化体验,参考下文可选方案 // 调用接口提交数据 axios.post('/你的提交接口地址', { rows }) .then(res => { /* 提交成功后续逻辑 */ }) .catch(err => { /* 处理后端返回的校验错误 */ }) }
最终提交的payload结构参考:
{ "rows": [ { "date": "2024-05-01", "project_id": "P001", "hours": "8", "description": "需求开发" }, { "date": "2024-05-01", "project_id": "P001", "hours": "8", "description": "测试验证" } ] }
第二步:后端Laravel校验规则编写
distinct规则默认会校验数组内的每个元素是否完全重复,刚好匹配你「不允许所有字段完全相同的行、最多3个字段相同」的要求,校验规则写法如下:
// 控制器接收请求后的校验逻辑 public function store(Request $request) { $rules = [ 'rows' => 'required|array', 'rows.*.date' => 'required|date', 'rows.*.project_id' => 'required|string', 'rows.*.hours' => 'required|numeric|min:0|max:24', 'rows.*.description' => 'required|string', // 核心校验规则:rows数组内不存在完全相同的元素 'rows' => 'distinct', ]; // 自定义错误提示 $messages = [ 'rows.distinct' => '表单中存在完全相同的行,请修改后再提交', ]; $validated = $request->validate($rules, $messages); // 校验通过后的业务逻辑 }
可选:前端前置校验(优化用户体验)
如果不想每次都等待后端返回错误,可以在前端提交前先做一次重复校验,参考代码:
function checkDuplicateRows(rows) { const uniqueRowKeys = new Set(); for (const row of rows) { // 将行的所有字段拼接为唯一标识字符串用于比对 const rowKey = `${row.date}|${row.project_id}|${row.hours}|${row.description}`; if (uniqueRowKeys.has(rowKey)) { alert('存在完全相同的行,请修改后再提交'); return false; } uniqueRowKeys.add(rowKey); } return true; } // 在submit方法组装完rows后调用即可
规则可行性说明
- 默认的
distinct规则对数组元素做全字段比对,完全匹配你当前的需求,不需要额外开发自定义规则 - 如果后续业务调整,需要仅比对指定字段组合(比如仅要求日期+项目ID组合唯一),可以通过扩展
distinct参数或者自定义校验规则实现,改造成本极低
内容的提问来源于stack exchange,提问作者user16780927
相关产品推荐
相关产品推荐

