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的对话框详解与参数
Mar 08 Javascript
学习JavaScript设计模式之代理模式
Jan 12 Javascript
js H5 canvas投篮小游戏
Aug 18 Javascript
用jquery获取自定义的标签属性的值简单实例
Sep 17 Javascript
js实现非常棒的弹出div
Oct 06 Javascript
浅谈javascript中的事件冒泡和事件捕获
Dec 28 Javascript
Webpack中css-loader和less-loader的使用教程
Apr 27 Javascript
vue单页开发父子组件传值思路详解
May 18 Javascript
Node.js Koa2使用JWT进行鉴权的方法示例
Aug 17 Javascript
js实现文件上传功能 后台使用MultipartFile
Sep 08 Javascript
vue-next/runtime-core 源码阅读指南详解
Oct 25 Javascript
JS实现秒杀倒计时特效
Jan 02 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 $_SERVER当前完整url的写法
2009/11/12 PHP
php删除与复制文件夹及其文件夹下所有文件的实现代码
2013/01/23 PHP
php微信开发之百度天气预报
2016/11/18 PHP
在IIS下安装PHP扩展的方法(超简单)
2017/04/10 PHP
url 编码 js url传参中文乱码解决方案
2010/04/11 Javascript
js处理json以及字符串的比较等常用操作
2013/09/08 Javascript
jquery获取css中的选择器(实例讲解)
2013/12/02 Javascript
jquery动态改变form属性提交表单
2014/06/03 Javascript
jQuery动态创建html元素的常用方法汇总
2014/09/05 Javascript
Node.js中JavaScript操作MySQL的常用方法整理
2016/03/01 Javascript
Web前端开发之水印、图片验证码
2016/11/27 Javascript
微信小程序实现多个按钮toggle功能的实例
2017/06/13 Javascript
JavaScript hasOwnProperty() 函数实例详解
2017/08/04 Javascript
BootStrap Table实现server分页序号连续显示功能(当前页从上一页的结束序号开始)
2017/09/12 Javascript
完美解决linux下node.js全局模块找不到的情况
2018/05/16 Javascript
Vue绑定内联样式问题
2018/10/17 Javascript
JS判断两个数组或对象是否相同的方法示例
2019/02/28 Javascript
JavaScript如何获取一个元素的样式信息
2019/07/29 Javascript
vue之a-table中实现清空选中的数据
2019/11/07 Javascript
[45:32]Liquid vs LGD 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
[01:45]典藏宝瓶2+祈求者身心——这就是DOTA2TI9总奖金突破3000万美元的秘密
2019/07/21 DOTA
Python lambda表达式用法实例分析
2018/12/25 Python
利用python对mysql表做全局模糊搜索并分页实例
2020/07/12 Python
纯CSS和jQuery实现的在页面顶部显示的进度条效果2例(仿手机浏览器进度条效果)
2014/04/16 HTML / CSS
阿里健康官方海外旗舰店:阿里健康国际自营
2017/11/24 全球购物
世界上最好的精品店:Shoptiques
2018/02/05 全球购物
新西兰廉价汽车租赁:Snap Rentals
2018/09/14 全球购物
财务工作者先进事迹材料
2014/01/17 职场文书
小学校长先进事迹材料
2014/05/13 职场文书
诚信承诺书模板
2014/05/26 职场文书
环保口号大全
2014/06/12 职场文书
党内外群众意见范文
2015/06/02 职场文书
Python 批量下载阴阳师网站壁纸
2021/05/19 Python
教你用python实现一个无界面的小型图书管理系统
2021/05/21 Python
MySQL 百万级数据的4种查询优化方式
2021/06/07 MySQL
CSS实现单选折叠菜单功能
2021/11/01 HTML / CSS