在“新建/编辑”复用同一表单的场景中从草稿继续编辑后点击“提交”按钮结果产生了两条记录而非更新原记录。本文分析这类典型的“新建 vs 编辑”场景的常见问题及解决方案。一、问题背景1.1 业务场景一个支持草稿功能的表单模块包含以下两种操作操作入口预期行为新建记录点击“新建”按钮创建新记录继续编辑草稿点击草稿的“继续编辑”更新现有草稿记录1.2 问题现象用户操作流程新建一条记录 → 存为草稿产生草稿记录 A从列表点击草稿 A 的“继续编辑”修改内容后点击“提交”预期草稿 A 状态从“草稿”变为“已发布”实际新增一条“已发布”记录 B草稿 A 仍然存在 →数据重复1.3 根因分析编辑页面没有区分“新建”和“编辑”场景场景期望行为实际问题新建调用创建接口✅ 正常编辑调用更新接口❌ 未传 ID仍调用创建接口二、问题代码分析2.1 列表页跳转逻辑正确列表页的“继续编辑”按钮正确传递了 IDvuetemplate view v-ifitem.status 草稿 button clickeditItem(item)继续编辑/button /view /template script setup const editItem (item) { uni.navigateTo({ url: /pages/form/edit?id${item.id} // ✅ 正确传递 ID }); }; /script2.2 问题代码编辑页错误vuescript setup import { ref, onMounted } from vue; import { createRecord, getRecordDetail } from /api/record; const formData ref({ title: , description: // ❌ 没有 id 字段 }); onMounted(() { const pages getCurrentPages(); const id pages[pages.length - 1].options.id; if (id) { getRecordDetail({ id }).then(res { formData.value.title res.title; formData.value.description res.description; // ❌ 没有保存 id }); } }); const submitForm async () { // ❌ 始终调用创建接口 await createRecord(formData.value); }; /script2.3 修复方案正确vuescript setup import { ref, computed, onMounted } from vue; import { createRecord, updateRecord, getRecordDetail } from /api/record; const formData ref({ id: null, // ✅ 添加 id 字段 title: , description: }); const isEditMode computed(() !!formData.value.id); onMounted(() { const pages getCurrentPages(); const id pages[pages.length - 1].options.id; if (id) { getRecordDetail({ id }).then(res { formData.value { id: id, // ✅ 保存 id title: res.title, description: res.description }; }); } }); const submitForm async () { if (formData.value.id) { await updateRecord(formData.value); // ✅ 编辑 } else { await createRecord(formData.value); // ✅ 新建 } }; /script三、完整 Demo 代码3.1 API 封装javascript// api/demo.js export function createRecord(data) { return http.post(/demo/create, data); } export function updateRecord(data) { return http.post(/demo/update, data); } export function getRecordDetail(params) { return http.get(/demo/detail, { params }); }3.2 列表页完整vuetemplate view classlist-page button classcreate-btn clickcreateNew新建/button view v-foritem in list :keyitem.id classlist-item text{{ item.title }}/text view classstatus :classstatus- item.status{{ item.status }}/view button v-ifitem.status 草稿 clickeditItem(item)继续编辑/button button v-else-ifitem.status 已发布 clickeditItem(item)编辑/button /view /view /template script setup import { ref, onShow } from vue; import { getRecordList } from /api/demo; const list ref([]); const loadList async () { const res await getRecordList(); list.value res.list || []; }; const createNew () { uni.navigateTo({ url: /pages/form/edit }); }; const editItem (item) { uni.navigateTo({ url: /pages/form/edit?id${item.id} }); }; onShow(loadList); /script3.3 编辑页完整vuetemplate view classedit-page input v-modelformData.title placeholder请输入标题 / textarea v-modelformData.description placeholder请输入描述 / button clicksaveDraft存草稿/button button clicksubmitForm{{ isEditMode ? 更新 : 创建 }}/button /view /template script setup import { ref, computed, onMounted } from vue; import { createRecord, updateRecord, getRecordDetail } from /api/demo; const formData ref({ id: null, title: , description: , status: }); const isEditMode computed(() !!formData.value.id); onMounted(async () { const pages getCurrentPages(); const id pages[pages.length - 1].options.id; if (id) { const res await getRecordDetail({ id }); formData.value { id: id, title: res.title, description: res.description, status: res.status }; } }); const submitForm async () { formData.value.status 已发布; if (formData.value.id) { await updateRecord(formData.value); } else { await createRecord(formData.value); } uni.navigateBack(); }; const saveDraft async () { formData.value.status 草稿; if (formData.value.id) { await updateRecord(formData.value); } else { const res await createRecord(formData.value); formData.value.id res.id; // 新建后保存 ID } }; /script四、经验总结4.1 核心要点要点说明表单包含id字段用于区分新建 / 编辑加载详情时保存id确保后续提交时携带根据id选择接口有 id 调用更新无 id 调用创建新建成功后保存id避免重复创建如多次存草稿4.2 推荐判断方式javascript// 方式一通过表单 id const isEditMode computed(() !!formData.value.id); // 方式二通过路由参数 const isEditMode computed(() { const pages getCurrentPages(); return !!pages[pages.length - 1].options.id; });4.3 后端接口建议可选后端可统一为“保存”接口根据是否传入id自动判断javaPostMapping(/save) public Result save(RequestBody DTO dto) { if (dto.getId() ! null) { return service.update(dto); } else { return service.create(dto); } }4.4 预防措施编辑页初始化时明确保存id提交前打印表单数据确认id是否存在接口调用时明确区分创建和更新测试覆盖“新建 → 草稿 → 继续编辑 → 提交”完整流程五、总结维度问题解决数据表单没有id字段添加并在加载详情时赋值逻辑没有区分新建 / 编辑根据id是否存在选择不同接口接口始终调用创建接口有 id 调用更新无 id 调用创建一句话总结新建/编辑复用表单时id的传递和判断是区分两种模式的关键遗漏id就会导致编辑变新建、数据重复。