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 相关文章推荐
兼容IE和Firefox的javascript获取iframe文档内容的函数
Aug 15 Javascript
线路分流自动智能跳转代码,自动选择最快镜像网站(js)
Oct 31 Javascript
深入理解JavaScript系列(18):面向对象编程之ECMAScript实现
Mar 05 Javascript
浅析四种常见的Javascript声明循环变量的书写方式
Oct 14 Javascript
JS组件Bootstrap Table表格行拖拽效果实现代码
Aug 27 Javascript
javascript实现下拉提示选择框
Dec 29 Javascript
JQuery日期插件datepicker的使用方法
Mar 03 Javascript
canvas实现刮刮卡效果
Mar 14 Javascript
js判断数组是否包含某个字符串变量的实例
Nov 24 Javascript
在Vue-cli里应用Vuex的state和mutations方法
Sep 16 Javascript
ES6中的迭代器、Generator函数及Generator函数的异步操作方法
May 12 Javascript
vue实现拖拽的简单案例 不超出可视区域
Jul 25 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获取数组长度的方法(有实例)
2013/10/27 PHP
php输入流php://input使用示例(php发送图片流到服务器)
2013/12/25 PHP
Docker 如何布置PHP开发环境
2016/06/21 PHP
PHP Laravel中的Trait使用方法
2019/01/20 PHP
jscript之List Excel Color Values
2007/06/13 Javascript
JS对外部文件的加载及对IFRMAME的加载的实现,当加载完成后,指定指向方法(方法回调)
2011/07/04 Javascript
基于jquery的web页面日期格式化插件
2011/11/15 Javascript
浏览器加载、渲染和解析过程黑箱简析
2012/11/29 Javascript
JS操作数据库的实例代码
2013/10/17 Javascript
javascript读写json示例
2014/04/11 Javascript
nodejs教程之环境安装及运行
2014/11/21 NodeJs
JS实现回到页面顶部动画效果的简单实例
2016/05/24 Javascript
jQuery购物车插件jsorder用法(支持后台处理程序直接转换成DataTable处理)
2016/06/08 Javascript
JS判断日期格式是否合法的简单实例
2016/07/11 Javascript
最原始的jQuery注册验证方式
2016/10/11 Javascript
javascript判断firebug是否开启的方法
2016/11/23 Javascript
vue中各组件之间传递数据的方法示例
2017/07/27 Javascript
Vue监听事件实现计数点击依次增加的方法
2018/09/26 Javascript
python中日期和时间格式化输出的方法小结
2015/03/19 Python
给Python入门者的一些编程建议
2015/06/15 Python
举例讲解Python中的身份运算符的使用方法
2015/10/13 Python
Python验证文件是否可读写代码分享
2017/12/11 Python
利用python计算时间差(返回天数)
2019/09/07 Python
Django项目使用ckeditor详解(不使用admin)
2019/12/17 Python
世界上最大的售后摩托车零配件超市:J&P Cycles
2017/12/08 全球购物
贝尔帐篷精品店:Bell Tent Boutique
2019/06/12 全球购物
法雷奥SQA(electric)面试问题
2016/01/23 面试题
简历里的自我评价范文
2014/02/24 职场文书
五一促销活动总结
2014/07/01 职场文书
委托书怎么写
2014/07/31 职场文书
2015年小学生新年寄语
2014/12/08 职场文书
平遥古城导游词
2015/02/03 职场文书
廉政承诺书2015
2015/04/28 职场文书
房屋维修申请报告
2015/05/18 职场文书
JS监听Esc 键触发事键
2021/04/14 Javascript
高通2023 年将发布高性能PC处理器
2022/04/29 数码科技