一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Vue 导航守卫如何在问卷调查系统中拦截未答完题目的直接关闭

时间:2026-09-06 16:09:49 编辑:袖梨 来源:一聚教程网

问卷系统防未答完离开需双重拦截:先用 Vue Router 的 beforeRouteLeave 守卫判断 isDirty 并阻止路由跳转,再用 window.beforeunload 事件覆盖刷新、关闭等所有卸载场景,配合 sessionStorage 草稿保存与状态同步优化体验。

在问卷调查系统中,防止用户未答完题目就关闭页面或跳转,核心是利用 Vue Router 的导航守卫配合浏览器原生事件,做两层拦截:路由跳转前判断、页面卸载前提醒。

监听路由跳转,拦截未提交的问卷页

对问卷填写页(如 /survey/:id)设置组件内守卫 beforeRouteLeave,它在用户点击链接、调用 router.push 或浏览器后退时触发,且能访问当前组件实例。

  1. 在问卷组件中,通过 data 或 computed 维护一个 isDirty 标志(例如:表单有任意字段被修改但未提交)
  2. beforeRouteLeave 中检查该标志,若为 true,弹出确认框;用户点“取消”则调用 next(false) 阻止跳转
  3. 注意:该守卫无法拦截直接刷新或关闭标签页,需配合下一层机制

捕获页面卸载,防止意外刷新或关闭

仅靠路由守卫不够,必须补充 beforeunload 事件——它是浏览器级钩子,覆盖所有退出场景(刷新、关闭、地址栏输入、前进/后退)。

  1. 在问卷组件 mounted 钩子中添加监听:window.addEventListener('beforeunload', handleBeforeUnload)
  2. handleBeforeUnload 函数返回字符串(现代浏览器会忽略内容,但必须返回值才能触发提示),例如:return '您还有未提交的题目,确定要离开吗?'
  3. beforeUnmount 或提交成功后移除监听,避免内存泄漏和误提示

状态同步与用户体验优化

单纯弹窗容易引起反感,建议配合状态管理提升体验:

  1. 将“是否已答题”状态存入 sessionStorage,即使刷新也能恢复草稿并继续拦截
  2. 在拦截提示中提供“保存草稿”按钮(调用本地保存逻辑),再允许离开
  3. 对已提交的问卷页,自动清除 beforeunload 监听,并将 isDirty 置为 false

不复杂但容易忽略:beforeunload 只能显示浏览器默认提示,无法自定义样式或按钮;而 beforeRouteLeave 对应的是可控的 Vue 导航流程。两者结合,才构成完整防护。

热门栏目