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 可以拖动的DIV(二)
Jun 26 Javascript
jquery一般方法介绍 入门参考
Jun 21 Javascript
js禁止页面刷新禁止用F5键刷新禁止右键的示例代码
Sep 23 Javascript
jQuery.extend()、jQuery.fn.extend()扩展方法示例详解
May 08 Javascript
jquery form表单获取内容以及绑定数据
Feb 24 Javascript
JavaScript鼠标事件,点击鼠标右键,弹出div的简单实例
Aug 03 Javascript
BootStrap 超链接变按钮的实现方法
Sep 25 Javascript
input框中的name和id的区别
Nov 16 Javascript
jQuery实现监听下拉框选中内容发生改变操作示例
Jul 13 jQuery
JS div匀速移动动画与变速移动动画代码实例
Mar 26 Javascript
Javascript数组方法reduce的妙用之处分享
Jun 10 Javascript
Vue父子之间值传递的实例教程
Jul 02 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中的一些常用函数收集
2015/05/26 PHP
PHP数据对象PDO操作技巧小结
2016/09/27 PHP
FormValid0.5版本发布,带ajax自定义验证例子
2007/08/17 Javascript
javascript优先加载笔记代码
2008/09/30 Javascript
combox改进版 页面原型参考dojo的,比网上jQuery的那些combox功能强,代码更小
2010/04/15 Javascript
引入JS文件IE6报语法错误或缺少对象问题的解决方法
2014/01/09 Javascript
js获取UserControl内容为拼html时提供方便
2014/11/02 Javascript
FF(火狐)浏览器无法执行window.close()解决方案
2014/11/13 Javascript
如何用js 实现依赖注入的思想,后端框架思想搬到前端来
2015/08/03 Javascript
网页收藏夹显示ICO图标(代码少)
2015/08/04 Javascript
js实现跨域的几种方法汇总(图片ping、JSONP和CORS)
2015/10/25 Javascript
Spring MVC中Ajax实现二级联动的简单实例
2016/07/06 Javascript
AngularJS入门教程之Select(选择框)详解
2016/07/27 Javascript
BootStrap实现轮播图效果(收藏)
2016/12/30 Javascript
js 转义字符及URI编码详解
2017/02/28 Javascript
React Native使用百度Echarts显示图表的示例代码
2017/11/07 Javascript
JS使用Date对象实时显示当前系统时间简单示例
2018/08/23 Javascript
详解VUE项目中安装和使用vant组件
2019/04/28 Javascript
jQuery实现雪花飘落效果
2020/08/02 jQuery
antd vue 刷新保留当前页面路由,保留选中菜单,保留menu选中操作
2020/08/06 Javascript
浅谈Python由__dict__和dir()引发的一些思考
2017/10/30 Python
Python3.5基础之NumPy模块的使用图文与实例详解
2019/04/24 Python
Python 50行爬虫抓取并处理图灵书目过程详解
2019/09/20 Python
使用python和pygame制作挡板弹球游戏
2019/12/03 Python
使用tqdm显示Python代码执行进度功能
2019/12/08 Python
Python3实现mysql连接和数据框的形成(实例代码)
2020/01/17 Python
纯CSS3实现的8种Loading动画效果
2014/07/05 HTML / CSS
CSS3 transforms应用于背景图像的解决方法
2019/04/16 HTML / CSS
浅谈HTML5 服务器推送事件(Server-sent Events)
2017/08/01 HTML / CSS
Bravofly德国:预订廉价航班和酒店
2019/09/22 全球购物
信息管理员岗位职责
2013/12/01 职场文书
商务经理岗位职责
2014/08/03 职场文书
个人对照检查材料思想汇报
2014/09/26 职场文书
先进党支部事迹材料
2014/12/24 职场文书
Java常用函数式接口总结
2021/06/29 Java/Android
数据库之SQL技巧整理案例
2021/07/07 SQL Server