动态表单草稿保存与加载的关键是精准维护结构、类型和唯一标识:每行需UUID等稳定key,v-for绑定该key;完整序列化含嵌套字段与附件元信息;加载时严格转换数值、布尔、日期类型;用isDraftLoaded控制渲染时机确保一次正确渲染。

动态表单的草稿保存和加载,关键不在“存”,而在“怎么存得准、读得对”。很多问题不是没保存,而是保存时丢了结构、类型或标识,导致加载后数据错位、丢失或计算异常。
确保每项动态内容都有唯一身份
动态添加的行(比如费用明细、问卷题目)必须带稳定、不可复用的唯一 ID,不能用数组索引(index)做 key 或标识。Vue 会因 key 不稳定而错误复用或销毁 DOM,造成输入内容错乱或消失。
- 添加新行时生成 UUID 或时间戳+随机数:
id: Date.now() + '-' + Math.random().toString(36).substr(2, 9) - 所有嵌套字段(如明细里的数量、单价)都应挂载在该行的 id 对应对象下,避免扁平化存储
- 渲染列表时,
v-for的 :key 必须是这个唯一 id,不是 index
完整序列化整个表单结构
草稿数据必须包含所有可变部分:基础字段 + 动态列表 + 文件元信息。常见错误是只保存顶层字段,漏掉嵌套数组或对象。
从零开始编排 SpringBoot+Vue 全栈项目工作流,适用于新建全栈项目或完整脚手架请求,触发后依次调用 product‑spec‑builder(需求调研)等模块。
- 构建保存数据时,显式提取全部字段:
{ title, type, items: formData.items, attachments: formData.attachments.map(a => ({ id: a.id, name: a.name, url: a.url })) } - 附件不能只存文件对象(浏览器 File 实例无法序列化),要存上传后的服务端 ID 或临时 URL + 元信息
- 使用
JSON.stringify()前,先检查是否有函数、undefined、Date 等非法值;必要时用dayjs格式化日期,用Number()显式转数字
加载时严格还原数据类型与结构
后端返回的草稿数据通常是字符串或 number 字面量,前端需主动转换回预期类型,否则会导致校验失败、计算出错或组件不响应。
- 数量、单价等数值字段,赋值前统一用
Number(value)转换,避免字符串拼接 - 布尔字段(如是否必填)接收
"1"、"true"或1时,用value === true || value === 'true' || value === '1'判断 - 日期字段用
dayjs(value).toDate()转为 Date 实例,再传给 DatePicker 组件 - 动态列表加载后,逐项检查是否存在 id,缺失则跳过或补默认结构,防止渲染异常
控制好组件渲染时机
别让空数据抢先渲染一次,再被真实草稿覆盖。尤其在异步加载场景下,初始状态应保持“未就绪”,直到草稿数据真正落地。
- 用一个
isDraftLoaded响应式标志位控制表单是否可交互;初始为false -
loadDraft()完成后才设为true,并把数据深拷贝赋给表单响应式对象 - 模板中加
v-if="isDraftLoaded",确保 DOM 只基于最终数据渲染一次 - 避免在
onMounted里直接调用loadDraft()后立即关闭 loading —— 应在await loadDraft()之后再更新状态
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









