vue单页面实现当前页面刷新或跳转时提示保存


Posted in Javascript onNovember 02, 2018

前言

最近公司vue项目中有一个需求,需要在当前页面刷新或跳转时提示保存并可取消刷新,以防止填写的表单内容丢失。刚开始思考觉得很简单,直接在Router的钩子中判断就好了,但是会发现还有新的问题存在,浏览器刷新和当前页面关闭的时候无法监听,最终用window.onbeforeunload成功解决,所以用这篇文章简单记录下整个解决过程。

vue-Router的钩子:

路由钩子可以分为全局的,单个路由独享的以及组件级别的,解决上述需求只用到了组件级别的路由钩子,所以本文只介绍组件级别的路由钩子,全局的和单个路由独享的路由钩子有需要的同学可以去vue-router官网查看介绍:

组件级别路由钩子分为三种:

  1. beforeRouteEnter:当成功获取并能进入路由(在渲染该组件的对应路由被 confirm 前)
  2. beforeRouteUpdate:在当前路由改变,但是该组件被复用时调用
  3. beforeRouteLeave:导航离开该组件的对应路由时调用

具体的介绍和写法如下:

const Foo = {
 template: `...`,
 beforeRouteEnter (to, from, next) {
 // 在渲染该组件的对应路由被 confirm 前调用
 // 不!能!获取组件实例 `this`
 // 因为当守卫执行前,组件实例还没被创建
 // 可以通过传一个回调给 next来访问组件实例
 next(vm => { 
   // 通过 `vm` 访问组件实例
  })
 },
 beforeRouteUpdate (to, from, next) {
 // 在当前路由改变,但是该组件被复用时调用
 // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
 // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
 // 可以访问组件实例 `this`
 // 不支持传递回调(因为this实例已经创建可以获取到,所以没必要)
 next()
 },
 beforeRouteLeave (to, from, next) {
 // 导航离开该组件的对应路由时调用
 // 可以访问组件实例 `this`
 // 该导航可以通过 next(false) 来取消。
 const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
 if (answer) {
  next()
 } else {
 // 不支持传递回调(因为this实例已经创建可以获取到,所以没必要)
  next(false)
 }
 }
}

注意:在刷新当前页面时候,beforeRouteLeave不会触发,它只在进入到其他页面时候才会触发,但是beforeRouteEnter会在刷新的时候触发。

通过beforeRouteLeave这个路由钩子,我们就可以在用户要离开此页面时候进行提示了!

beforeRouteLeave (to, from, next) {
 const answer = window.confirm('当前页面数据未保存,确定要离开![image](http://note.youdao.com/favicon.ico)?')
 if (answer) {
  next()
 } else {
  next(false)
 }
 }

显示的提示框如下:

vue单页面实现当前页面刷新或跳转时提示保存

监听浏览器的刷新、页面关闭事件

但是,这个时候就实现了我们最终的需求了么?并没有,还有一步:用window.onbeforeunload监听浏览器的刷新事件,当然为了防止从当前单页面跳到其他页面之后,在刷新所在新的页面还会触发window上的onbeforeunload的问题,我们不仅要及时的添加onbeforeunload事件,更要及时删除此事件,下面有两种解决方法可供选择:

通过判断它的路由是否是当前需要添加禁止刷新的页面

mounted() {
 window.onbeforeunload = function (e) {
  if(_this.$route.fullPath =="/layout/add"){
   e = e || window.event;
   // 兼容IE8和Firefox 4之前的版本
   if (e) {
   e.returnValue = '关闭提示';
   }
   // Chrome, Safari, Firefox 4+, Opera 12+ , IE 9+
   return '关闭提示';
  }else{
  window.onbeforeunload =null
  }
}
};

在destory或者beforeDestory的生命周期中直接将onbeforeunload事件置空

mounted() {
 window.onbeforeunload = function (e) {
  e = e || window.event;
  // 兼容IE8和Firefox 4之前的版本
  if (e) {
   e.returnValue = '关闭提示';
  }
  // Chrome, Safari, Firefox 4+, Opera 12+ , IE 9+
  return '关闭提示';
 }
};
destroyed() {
  window.onbeforeunload = null
 }

显示的提示框如下:

vue单页面实现当前页面刷新或跳转时提示保存

总结

最终,在beforeRouteLeave和onbeforeunload的共同作用下,这个刷新、跳转或者关闭等情况下需要提示保存的需求完美解决!但是,还有一点点小遗憾,就是onbeforeunload中弹框的自定义提示语设置始终无法生效,大家要是有更加合适的处理办法,欢迎多多交流指正!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript中关于break,continue的特殊用法与介绍
May 24 Javascript
JScript分割字符串示例代码
Sep 04 Javascript
JavaScript跨平台的开源框架NativeScript
Mar 24 Javascript
text-align:justify实现文本两端对齐 兼容IE
Aug 19 Javascript
JS中如何实现点击a标签返回页面顶部的问题
Jan 19 Javascript
jQuery EasyUI开发技巧总结
Sep 26 jQuery
Vue动画事件详解及过渡动画实例
Feb 09 Javascript
js取0-9随机取4个数不重复的数字代码实例
Mar 27 Javascript
jquery实现垂直手风琴菜单
Mar 04 jQuery
Python版实现微信公众号扫码登陆
May 28 Javascript
搭建vscode+vue环境的详细教程
Aug 31 Javascript
JS绘图Flot如何实现动态可刷新曲线图
Oct 16 Javascript
BootStrap中的模态框(modal,弹出层)功能示例代码
Nov 02 #Javascript
Bootstrap的aria-label和aria-labelledby属性实例详解
Nov 02 #Javascript
axios使用拦截器统一处理所有的http请求的方法
Nov 02 #Javascript
vue实现与安卓、IOS交互的方法
Nov 02 #Javascript
解决iview多表头动态更改列元素发生的错误的方法
Nov 02 #Javascript
JavaScript 点击触发复制功能实例详解
Nov 02 #Javascript
微信小程序实现留言板(Storage)
Nov 02 #Javascript
You might like
PHP实现二维数组去重功能示例
2017/01/12 PHP
PHP批量删除jQuery操作
2017/07/23 PHP
关于laravel5.5的定时任务详解(demo)
2019/10/23 PHP
文本框根据输入内容自适应高度的代码
2011/10/24 Javascript
javascript 处理null及null值示例
2014/06/09 Javascript
自己封装的常用javascript函数分享
2015/01/07 Javascript
浅谈angularJS 作用域
2015/07/05 Javascript
JavaScript实现99乘法表及隔行变色实例代码
2016/02/24 Javascript
jQuery+ajax实现实用的点赞插件代码
2016/07/06 Javascript
AngularJs IE Compatibility 兼容老版本IE
2016/09/01 Javascript
jQuery鼠标移动图片上实现放大效果
2017/06/25 jQuery
jQuery 实现图片的依次加载图片功能
2017/07/06 jQuery
Bootstrap datepicker日期选择器插件使用详解
2017/07/26 Javascript
seajs中最常用的7个功能、配置示例
2017/10/10 Javascript
vue拦截器实现统一token,并兼容IE9验证功能
2018/04/26 Javascript
详解create-react-app 自定义 eslint 配置
2018/06/07 Javascript
Angular服务Request异步请求的实例讲解
2018/08/13 Javascript
使用pkg打包Node.js应用的方法步骤
2018/10/19 Javascript
Vue.js页面中有多个input搜索框如何实现防抖操作
2019/11/04 Javascript
Vue通过WebSocket建立长连接的实现代码
2019/11/05 Javascript
[01:14:12]2018DOTA2亚洲邀请赛4.7 总决赛 LGD vs Mineski 第二场
2018/04/09 DOTA
Python中使用scapy模拟数据包实现arp攻击、dns放大攻击例子
2014/10/23 Python
python让图片按照exif信息里的创建时间进行排序的方法
2015/03/16 Python
PyQtGraph在pyqt中的应用及安装过程
2019/08/04 Python
Python 3.8 新功能大揭秘【新手必学】
2020/02/05 Python
pycharm设置当前工作目录的操作(working directory)
2020/02/14 Python
2014年圣诞节倒计时网页的制作过程
2014/12/05 HTML / CSS
纽约现代艺术博物馆商店:MoMA STORE(室内家具和杂货商品)
2016/08/02 全球购物
应届毕业生简历自我评价
2014/01/31 职场文书
消防工作实施方案
2014/06/09 职场文书
学校欢迎标语
2014/06/18 职场文书
2014年小学教学工作总结
2014/11/13 职场文书
2014年党风廉政建设工作总结
2014/11/19 职场文书
政工师工作总结2015
2015/05/26 职场文书
聘用合同范本
2015/09/21 职场文书
使用compose函数优化代码提高可读性及扩展性
2022/06/16 Javascript