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 相关文章推荐
仅IE6/7/8中innerHTML返回值忽略英文空格的问题
Apr 07 Javascript
jquery绑定原理 简单解析与实现代码分享
Sep 06 Javascript
angularJS与bootstrap结合实现动态加载弹出提示内容
Oct 16 Javascript
详述JavaScript实现继承的几种方式(推荐)
Mar 22 Javascript
jQuery使用正则表达式限制文本框只能输入数字
Jun 18 Javascript
jquery结合html实现中英文页面切换
Nov 29 Javascript
jQuery UI制作选项卡(tabs)
Dec 13 Javascript
写给小白看的JavaScript异步
Nov 29 Javascript
vue升级之路之vue-router的使用教程
Aug 14 Javascript
Vue面试题及Vue知识点整理
Oct 07 Javascript
如何使用Node.js爬取任意网页资源并输出PDF文件到本地
Jun 17 Javascript
微信小程序导入Vant报错VM292:1 thirdScriptError的解决方法
Aug 01 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 信息采集程序代码
2009/03/17 PHP
PHP中mysqli_affected_rows作用行数返回值分析
2014/12/26 PHP
必须收藏的23个php实用代码片段
2016/02/02 PHP
Yii框架where查询用法实例分析
2019/10/22 PHP
javascript 一段左右两边随屏滚动的代码
2009/06/18 Javascript
js关闭父窗口时关闭子窗口
2013/04/01 Javascript
javascript检测是否联网的实现代码
2014/09/28 Javascript
node-webkit打包成exe文件被360误报木马的解决方法
2015/03/11 Javascript
jQuery prototype冲突的2种解决方法(附demo示例下载)
2016/01/21 Javascript
基于JQuery打造无缝滚动新闻步骤详解
2016/03/31 Javascript
CSS3 media queries结合jQuery实现响应式导航
2016/09/30 Javascript
谈谈JavaScript数组常用方法总结
2017/01/24 Javascript
extjs简介_动力节点Java学院整理
2017/07/17 Javascript
浅谈Vuex@2.3.0 中的 state 支持函数申明
2017/11/22 Javascript
javascript连接mysql与php通过odbc连接任意数据库的实例
2017/12/27 Javascript
JavaScript运行原理分析
2018/02/09 Javascript
从Vuex中取出数组赋值给新的数组,新数组push时报错的解决方法
2018/09/18 Javascript
webpack4+express+mongodb+vue实现增删改查的示例
2018/11/08 Javascript
[01:54]胎教DOTA2 准妈妈玩家现身中国区预选赛
2016/06/26 DOTA
python模拟登陆Tom邮箱示例分享
2014/01/13 Python
Cpy和Python的效率对比
2015/03/20 Python
轻松掌握python设计模式之访问者模式
2016/11/18 Python
Python中分支语句与循环语句实例详解
2018/09/13 Python
Python 实现两个服务器之间文件的上传方法
2019/02/13 Python
Django使用中间键实现csrf认证详解
2019/07/22 Python
pyinstaller将含有多个py文件的python程序做成exe
2020/04/29 Python
Keras框架中的epoch、bacth、batch size、iteration使用介绍
2020/06/10 Python
Python函数__new__及__init__作用及区别解析
2020/08/31 Python
HTML5新特性之语义化标签
2017/10/31 HTML / CSS
TALLY WEiJL法国网上商店:服装、时装及配饰
2019/08/31 全球购物
写一个函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度
2015/11/18 面试题
电子商务专业个人的自我评价分享
2013/10/29 职场文书
幼儿园庆六一活动方案
2014/03/06 职场文书
学习全国两会精神心得体会范文
2014/03/17 职场文书
员工规章制度范本
2015/08/07 职场文书
《勇者辞职不干了》上卷BD发售宣传CM公开
2022/04/08 日漫