用 watch 实现自动保存草稿的核心是精准监听内容变化并克制保存:通过防抖、脏检查、失焦兜底控制节奏,失败时本地缓存并反馈状态,兼容非响应式编辑器需手动桥接事件。

用 watch 实现自动保存草稿,核心是监听编辑器内容变化,并在合适时机触发保存逻辑,避免频繁请求和覆盖用户操作。关键不在“一直存”,而在“存得准、存得稳”。
监听内容变化:用 watch 监测响应式数据
如果你的编辑器内容绑定在 Vue 的响应式变量(比如 ref 或 data 中的字段)上,直接用 watch 监听即可:
- 对单个字符串或简单对象,用
watch(content, callback, { debounce: 800 })(Vue 3.4+ 支持原生防抖) - 若内容是复杂结构(如富文本 JSON、带光标位置的对象),建议监听其序列化结果:
watch(() => JSON.stringify(editorState), saveDraft),但注意性能,可加deep: true替代 - 避免监听整个 editor 实例(如 Quill 或 Tiptap 的实例对象),它内部变化频繁且非响应式,容易误触发
控制保存节奏:防抖 + 脏检查 + 手动触发兜底
自动保存不是越勤越好,要平衡体验与服务压力:
- 默认启用 1–2 秒防抖:用户停顿输入后才保存,不打断思考流
- 加入“脏检查”:仅当新内容与上次已保存版本不同时才发起请求,避免无意义更新(可用
JSON.stringify(new) !== lastSavedHash快速比对) - 绑定窗口失焦(
beforeunload)和编辑器失去焦点事件,强制保存一次,防止意外关闭丢稿
保存失败处理:本地缓存 + 用户可见反馈
网络不稳定时,不能让草稿消失:
- 保存失败时,把当前内容写入
localStorage,键名可带时间戳或文档 ID,例如draft-${docId} - 编辑器加载时优先检查 localStorage 是否存在未同步草稿,弹窗询问是否恢复(别静默覆盖)
- 在 UI 角落显示小状态条:“已保存” / “保存中…” / “网络异常,已暂存本地”,让用户有掌控感
兼容非响应式编辑器:手动触发 watch 源
像 CodeMirror、Monaco 或原生 textarea 不自动触发响应式更新,需桥接:
- 监听
input或change事件,手动赋值给响应式变量:content.value = $event.target.value - 使用
watchEffect主动收集依赖:在回调里读取editor.getValue(),只要该方法被调用,就会被追踪 - 对支持 onChange 回调的编辑器(如 Tiptap),直接在回调里调用
saveDraft(),再由你控制节流逻辑
自动保存不是技术炫技,而是减少用户心理负担。重点是感知变化、克制请求、守住数据、及时反馈。做对这四点,草稿功能就立住了。










