vue单页面:当前页面刷新或跳转时提示保存

前言

最近公司vue项目中有一个需求,须要在当前页面刷新或跳转时提示保存并可取消刷新,以防止填写的表单内容丢失。刚开始思考以为很简单,直接在Router的钩子中判断就行了,可是会发现还有新的问题存在,浏览器刷新和当前页面关闭的时候没法监听,最终用window.onbeforeunload成功解决,因此用这篇文章简单记录下整个解决过程。

vue-Router的钩子:

路由钩子能够分为全局的,单个路由独享的以及组件级别的,解决上述需求只用到了组件级别的路由钩子,因此本文只介绍组件级别的路由钩子,全局的和单个路由独享的路由钩子有须要的同窗能够去vue-router官网查看介绍:html

组件级别路由钩子分为三种:vue

  • beforeRouteEnter:当成功获取并能进入路由(在渲染该组件的对应路由被 confirm 前)
  • beforeRouteUpdate:在当前路由改变,可是该组件被复用时调用
  • beforeRouteLeave:导航离开该组件的对应路由时调用

具体的介绍和写法以下:vue-router

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这个路由钩子,咱们就能够在用户要离开此页面时候进行提示了!ide

beforeRouteLeave (to, from, next) {
    const answer = window.confirm('当前页面数据未保存,肯定要离开?')
    if (answer) {
        next()
    } else {
        next(false)
    }
  }

显示的提示框以下:ui

image

监听浏览器的刷新、页面关闭事件

可是,这个时候就实现了咱们最终的需求了么?并无,还有一步:用window.onbeforeunload监听浏览器的刷新事件,固然为了防止从当前单页面跳到其余页面以后,在刷新所在新的页面还会触发window上的onbeforeunload的问题,咱们不只要及时的添加onbeforeunload事件,更要及时删除此事件,下面有两种解决方法可供选择:this

  1. 经过判断它的路由是不是当前须要添加禁止刷新的页面
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
      }
}
};
  1. 在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
    }

显示的提示框以下:spa

image

总结

最终,在beforeRouteLeave和onbeforeunload的共同做用下,这个刷新、跳转或者关闭等状况下须要提示保存的需求完美解决!可是,还有一点点小遗憾,就是onbeforeunload中弹框的自定义提示语设置始终没法生效,你们要是有更加合适的处理办法,欢迎多多交流指正!code

相关文章
相关标签/搜索