核心是用 watch 深度监听表单整体状态是否偏离初始快照,结合路由守卫和 beforeunload 事件实现全场景未保存提示:页面加载时用 structuredclone 或 json.stringify 保存初始值,watch 配合 deep: true 和 isequal 判断脏状态,提交后更新快照并重置;路由跳转用 onbeforerouteleave 拦截并弹窗确认;关闭/刷新时通过 beforeunload 触发浏览器原生提示,并注意事件清理;辅以顶部微提示、localstorage 自动暂存、提交时重置 dirty 状态及引用类型标准化等细节提升体验。

核心是用 watch 深度监听表单数据变化,结合初始快照比对判断“是否真改”,再联动路由守卫和页面卸载事件触发提示——不是监听每个输入框,而是盯住整个表单状态是否偏离初始值。
监听表单整体状态,避免逐字段罗列
把表单对象(如 reactive 或 ref 包裹的 form)作为 watch 目标,配合 deep: true 和稳定比对逻辑:
- 页面加载时用
structuredClone(form)或JSON.stringify(form)保存初始快照(注意别直接赋引用) - 用
watch(form, () => { isDirty.value = !isEqual(form, initialForm); }, { deep: true })判断差异(isEqual可用 Lodash,或自写简易逻辑:忽略空格、大小写、只比关键字段) - 提交成功后,立刻更新
initialForm快照,并重置isDirty.value = false
路由跳转时拦截并弹出自定义提示
Vue Router 的组件级守卫能精准控制导航行为,但不覆盖关闭/刷新:
使用 `@ainative/vue-sdk` 为 Vue 3 应用添加 AI 聊天功能。适用于以下场景:(1) 安装 `@ainative/vue-sdk`,(2) 在 Vue 组件中使用 `useChat` 组合式函数,(3) 提供……
- 在表单组件内使用
onBeforeRouteLeave(Vue 3),检查isDirty.value - 若为 true,调用
ElMessage.confirm或ElMessageBox弹窗,用户点“确定”才执行next(),点“取消”则next(false) - 注意:不能在 confirm 回调里直接调
next(),需确保用户手势触发(现代浏览器限制非交互式调用)
关闭或刷新页面时兜底提醒
beforeunload 是唯一能捕获所有离开场景(含地址栏输入、关标签页)的机制:
- 当
isDirty.value === true时,给window绑定beforeunload事件,返回任意字符串(如"您有未保存的更改") - 该事件会触发浏览器原生提示,样式不可定制,但兼容性最好
- 路由切换或组件卸载前,记得
window.removeEventListener('beforeunload', handler),防止内存泄漏
提升体验的关键细节
光有提示不够,用户需要感知+可控+安心:
- 页面顶部加一行微提示:“⚠️ 您有未保存的更改” + “保存”按钮,降低决策压力
- 用户停留超 30 秒未提交,自动将当前 form 存入
localStorage,下次进入时恢复 - 禁用提交按钮期间(如 loading 状态),同步设
isDirty.value = false,避免重复提醒 - 对 Date、数组等引用类型字段,监听前先标准化(如转 ISO 字符串),防止因新实例生成误判 dirty
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









