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学习笔记(九)javascript中的原型(prototype)及原型链的继承方式
Apr 12 Javascript
jQuery EasyUI API 中文文档 - Panel面板
Sep 30 Javascript
Jquery实现页面加载时弹出对话框代码
Apr 19 Javascript
JQuery中如何传递参数如click(),change()等具体实现
Apr 28 Javascript
node.js中的fs.chmodSync方法使用说明
Dec 18 Javascript
Node.js实现批量去除BOM文件头
Dec 20 Javascript
javascript实现左右控制无缝滚动
Dec 31 Javascript
Jquery中Event对象属性小结
Feb 27 Javascript
编写高性能Javascript代码的N条建议
Oct 12 Javascript
运用js教你轻松制作html音乐播放器
Apr 17 Javascript
基于jQuery使用Ajax动态执行模糊查询功能
Jul 05 jQuery
新手快速入门微信小程序组件库 iView Weapp
Jun 24 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 ignore_user_abort函数详细介绍和使用实例
2014/07/15 PHP
php通过两层过滤获取留言内容的方法
2016/07/11 PHP
PHP文件下载实例代码浅析
2016/08/17 PHP
PHP通过调用新浪API生成t.cn格式短网址链接的方法详解
2019/02/20 PHP
php设计模式之策略模式应用案例详解
2019/06/17 PHP
Laravel框架实现文件上传的方法分析
2019/09/29 PHP
PHP实现常用排序算法的方法
2020/02/05 PHP
点弹代码 点击页面任何位置都可以弹出页面效果代码
2012/09/17 Javascript
JS弹出窗口代码大全(详细整理)
2012/12/21 Javascript
Jquery Uploadify上传带进度条的简单实例
2014/02/12 Javascript
基于jquery实现省市联动特效
2015/12/17 Javascript
深入解析Backbone.js框架的依赖库Underscore.js的作用
2016/05/07 Javascript
jQuery的each循环用法简单示例
2016/06/12 Javascript
ES6新特性之函数的扩展实例详解
2017/04/01 Javascript
gulp教程_从入门到项目中快速上手使用方法
2017/09/14 Javascript
angularjs路由传值$routeParams详解
2020/09/05 Javascript
vue中的计算属性的使用和vue实例的方法示例
2017/12/04 Javascript
浅谈redux以及react-redux简单实现
2018/08/28 Javascript
浅谈 Webpack 如何处理图片(开发、打包、优化)
2019/05/15 Javascript
ES6 Class中实现私有属性的一些方法总结
2019/07/08 Javascript
[53:15]2018DOTA2亚洲邀请赛3月29日 小组赛A组 LGD VS TNC
2018/03/30 DOTA
[01:11:02]Secret vs Newbee 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
python实现点对点聊天程序
2018/07/28 Python
基于python实现简单网页服务器代码实例
2020/09/14 Python
Python Pandas list列表数据列拆分成多行的方法实现
2020/12/14 Python
使用 CSS3 中@media 实现网页自适应的示例代码
2020/03/24 HTML / CSS
HTML5之消息通知的使用(Web Notification)
2018/10/30 HTML / CSS
中国跨镜手机配件批发在线商店:TVC-Mall
2019/08/20 全球购物
英国家居用品和家居装饰品购物网站:Cox & Cox
2019/08/25 全球购物
四风问题自查自纠工作情况报告
2014/10/28 职场文书
学校端午节活动总结
2015/02/11 职场文书
2015仓库保管员年终工作总结
2015/05/13 职场文书
结婚典礼致辞
2015/07/28 职场文书
JS监听Esc 键触发事键
2021/04/14 Javascript
教你用Python matplotlib库制作简单的动画
2021/06/11 Python
聊聊mysql都有哪几种分区方式
2022/04/13 MySQL