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入门教程(3) js面向对象
Jan 31 Javascript
Ext javascript建立超链接,进行事件处理的实现方法
Mar 22 Javascript
让iframe子窗体取父窗体地址栏参数(querystring)
Oct 13 Javascript
JavaScript中的isXX系列是否继续使用的分析
Apr 16 Javascript
jQuery使用ajaxSubmit()提交表单示例
Apr 04 Javascript
JavaScript类型系统之正则表达式
Jan 05 Javascript
JavaScript实现的MD5算法完整实例
Feb 02 Javascript
浅谈js中的引用和复制(传值和传址)
Sep 18 Javascript
JS 终止执行的实现方法
Nov 24 Javascript
JS实现复选框的全选和批量删除功能
Apr 05 Javascript
vue实现的双向数据绑定操作示例
Dec 04 Javascript
vue 子组件watch监听不到prop的解决
Aug 09 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 5.5版本的array_column()函数
2014/10/24 PHP
PHP基于cookie与session统计网站访问量并输出显示的方法
2016/01/15 PHP
Yii2中事务的使用实例代码详解
2016/09/07 PHP
PHP count_chars()函数讲解
2019/02/14 PHP
javascript 单选框,多选框美化代码
2008/08/01 Javascript
JS 实现完美include载入实现代码
2010/08/05 Javascript
JavaScript直播评论发弹幕切图功能点集合效果代码
2016/06/26 Javascript
浅谈Koa2框架利用CORS完成跨域ajax请求
2018/03/06 Javascript
详解如何在webpack中做预渲染降低首屏空白时间
2018/08/22 Javascript
vue、react等单页面项目部署到服务器的方法及vue和react的区别
2018/09/29 Javascript
微信小程序实现日历效果
2018/12/28 Javascript
JavaScript数组、json对象、eval()函数用法实例分析
2019/02/21 Javascript
Vue组件系列开发之模态框
2019/04/18 Javascript
js比较两个单独的数组或对象是否相等的实例代码
2019/04/28 Javascript
JQuery特殊效果和链式调用操作示例
2019/05/13 jQuery
layui.use模块外部使用其内部定义的js封装函数方法
2019/09/16 Javascript
vue-quill-editor 自定义工具栏和自定义图片上传路径操作
2020/08/03 Javascript
vue组件暴露和.js文件暴露接口操作
2020/08/11 Javascript
ubuntu安装mysql pycharm sublime
2018/02/20 Python
python 列表删除所有指定元素的方法
2018/04/19 Python
python2与python3爬虫中get与post对比解析
2019/09/18 Python
Python脚本操作Excel实现批量替换功能
2019/11/20 Python
Python栈的实现方法示例【列表、单链表】
2020/02/22 Python
Python 自由定制表格的实现示例
2020/03/20 Python
keras 模型参数,模型保存,中间结果输出操作
2020/07/06 Python
Python Selenium XPath根据文本内容查找元素的方法
2020/12/07 Python
css3中less实现文字长阴影(long shadow)
2020/04/24 HTML / CSS
创造美妙香氛体验:Aera扩散器和香水
2018/11/25 全球购物
描述Cookie和Session的作用,区别和各自的应用范围,Session工作原理
2015/03/25 面试题
家长对小学生的评语
2014/01/28 职场文书
2014年单位植树节活动方案
2014/03/23 职场文书
社团活动总结报告
2014/06/27 职场文书
夏季药店促销方案
2014/08/22 职场文书
大学生违纪检讨书范文
2015/05/07 职场文书
关于职业道德的心得体会
2016/01/18 职场文书
《一面五星红旗》教学反思
2016/02/23 职场文书