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 相关文章推荐
JQuery 动画卷页 返回顶部 动画特效(兼容Chrome)
Feb 15 Javascript
js 判断checkbox是否选中的实现代码
Nov 23 Javascript
JavaScript中创建类/对象的几种方法总结
Nov 29 Javascript
js实现简单秒表走动的时钟特效
Mar 25 Javascript
基于jQuery实现交互体验社会化分享代码附源码下载
Jan 04 Javascript
JavaScript弹出对话框的三种方式
Mar 23 Javascript
浅谈vue-cli加载不到dev-server.js的解决办法
Nov 24 Javascript
vue + vuex todolist的实现示例代码
Mar 09 Javascript
JS字符串常用操作方法实例小结
Jun 24 Javascript
vue 源码解析之虚拟Dom-render
Aug 26 Javascript
layer.open弹层查看缩略图的原图,自适应大小的实例
Sep 05 Javascript
vue项目配置 webpack-obfuscator 进行代码加密混淆的实现
Feb 26 Vue.js
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
set_include_path在win和linux下的区别
2008/01/10 PHP
PHP源码之 ext/mysql扩展部分
2009/07/17 PHP
PHP中英混合字符串截取函数代码
2011/07/17 PHP
phpstorm配置Xdebug进行调试PHP教程
2014/12/01 PHP
Yii2 assets清除缓存的方法
2016/05/16 PHP
php 计算两个时间相差的天数、小时数、分钟数、秒数详解及实例代码
2016/11/09 PHP
PHP+Ajax实现的检测用户名功能简单示例
2019/02/12 PHP
基于jquery的气泡提示效果
2010/05/31 Javascript
解决js正则匹配换行问题实现代码
2012/12/10 Javascript
javascript获取隐藏元素(display:none)的高度和宽度的方法
2014/06/06 Javascript
javascript中传统事件与现代事件
2015/06/23 Javascript
jquery实现用户信息修改验证输入方法汇总
2015/07/18 Javascript
JS实现焦点图轮播效果的方法详解
2016/12/19 Javascript
基于JavaScript实现拖动滑块效果
2017/02/16 Javascript
Node.js通过身份证号验证年龄、出生日期与性别方法示例
2017/03/09 Javascript
浅谈JS获取元素的N种方法及其动静态讨论
2017/08/25 Javascript
jQuery实现获取table中鼠标click点击位置行号与列号的方法
2017/10/09 jQuery
Vue.JS项目中5个经典Vuex插件
2017/11/28 Javascript
浅析Vue项目中使用keep-Alive步骤
2018/07/27 Javascript
vue表单数据交互提交演示教程
2019/11/13 Javascript
Vue左滑组件slider使用详解
2020/08/21 Javascript
Python单元测试unittest的具体使用示例
2018/12/17 Python
Python爬虫实战之12306抢票开源
2019/01/24 Python
使用pickle存储数据dump 和 load实例讲解
2019/12/30 Python
Flask 上传自定义头像的实例详解
2020/01/09 Python
python GUI库图形界面开发之PyQt5状态栏控件QStatusBar详细使用方法实例
2020/02/28 Python
Python多线程:主线程等待所有子线程结束代码
2020/04/25 Python
各大浏览器 CSS3 和 HTML5 兼容速查表 图文
2010/04/01 HTML / CSS
Wiggle新西兰:自行车、跑步、游泳
2020/05/06 全球购物
描述内存分配方式以及它们的区别
2016/10/15 面试题
大学生标准推荐信范文
2013/11/25 职场文书
最美护士演讲稿
2014/08/27 职场文书
2014年惩防体系建设工作总结
2014/12/01 职场文书
违纪学生保证书
2015/02/27 职场文书
《桂花雨》教学反思
2016/02/19 职场文书
新学期新寄语,献给新生们!
2019/11/15 职场文书