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 拖拉缩放效果
Dec 10 Javascript
javascript 面向对象,实现namespace,class,继承,重载
Oct 29 Javascript
JS实现金额转换(将输入的阿拉伯数字)转换成中文的实现代码
Sep 30 Javascript
js图片滚动效果时间可随意设定当鼠标移上去时停止
Jun 26 Javascript
javascript+canvas制作九宫格小程序
Dec 28 Javascript
jQuery实现仿路边灯箱广告图片轮播效果
Apr 15 Javascript
Bootstrap每天必学之折叠
Apr 12 Javascript
onmouseover事件和onmouseout事件全面理解
Aug 15 Javascript
EasyUi 打开对话框后控件赋值及赋值后不显示的问题解决办法
Jan 19 Javascript
javascript 中设置window.location.href跳转无效问题解决办法
Feb 09 Javascript
浅谈用Webpack路径压缩图片上传尺寸获取的问题
Feb 22 Javascript
JavaScript 斐波那契数列 倒序输出 输出100以内的质数代码实例
Sep 11 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/05/07 PHP
关于PHP模板Smarty的初级使用方法以及心得分享
2013/06/21 PHP
一个简单且很好用的php分页类
2013/10/26 PHP
ThinkPHP字符串函数及常用函数汇总
2014/07/18 PHP
PHP常用排序算法实例小结【基本排序,冒泡排序,快速排序,插入排序】
2017/02/07 PHP
Paypal实现循环扣款(订阅)功能
2017/03/23 PHP
下拉框select的绑定示例
2014/09/04 Javascript
JavaScript获取数组最小值和最大值的方法
2015/06/09 Javascript
jQuery查看选中对象HTML代码的方法
2016/06/17 Javascript
基于jquery实现弹幕效果
2016/09/29 Javascript
基于Bootstrap仿淘宝分页控件实现代码
2016/11/07 Javascript
ionic实现下拉刷新载入数据功能
2017/05/11 Javascript
JS随机排序数组实现方法分析
2017/10/11 Javascript
使用vue官方提供的模板vue-cli搭建一个helloWorld案例分析
2018/01/16 Javascript
vue 简单自动补全的输入框的示例
2018/03/12 Javascript
JS中注入eval, Function等系统函数截获动态代码
2019/04/03 Javascript
Centos7 安装Node.js10以上版本的方法步骤
2019/10/15 Javascript
微信小程序实用代码段(收藏版)
2019/12/17 Javascript
Vue使用Three.js加载glTF模型的方法详解
2020/06/14 Javascript
[01:32]TI奖金增速竟因它再创新高!DOTA2勇士令状不朽珍藏Ⅰ饰品欣赏
2018/05/18 DOTA
使用python实现拉钩网上的FizzBuzzWhizz问题示例
2014/05/05 Python
基于Django与ajax之间的json传输方法
2018/05/29 Python
Pycharm导入Python包,模块的图文教程
2018/06/13 Python
Python制作词云图代码实例
2019/09/09 Python
python中rb含义理解
2020/06/18 Python
Keras SGD 随机梯度下降优化器参数设置方式
2020/06/19 Python
浅谈keras 模型用于预测时的注意事项
2020/06/27 Python
Java中采用什么结构来捕获、处理异常?各子句的顺序、功能如何
2013/10/07 面试题
安全检查管理制度
2014/02/02 职场文书
房屋买卖协议书范本
2014/09/27 职场文书
通讯稿格式及范文
2015/07/22 职场文书
《怀念母亲》教学反思
2016/02/19 职场文书
创业计划书之儿童理发店
2019/09/27 职场文书
教你怎么用Python操作MySql数据库
2021/05/31 Python
【DOTA2】总决赛血虐~ XTREME GAMING vs MAGMA - OGA DOTA PIT 2022 CN
2022/04/02 DOTA
ipad隐藏软件app图标方法
2022/04/19 数码科技