Vue实现离开页面二次确认

在项目开发中遇到用户编辑内容后未保存推出编辑页面时需要提示用户“当前数据未保存,是否退出”,实际开发中利用window.onbeforeunload方法与vue.$on方法在updated生命周期函数中做出相的判断,做出相应的操作。

准备

onbeforeunload 事件

在即将离开当前页面(刷新或关闭)时执行JavaScript

  • onbeforeunload 事件在即将离开当前页面(刷新或关闭)时触发
  • 该事件可用于弹出对话框,提示用户是继续浏览页面还是离开当前页面
  • 对话框默认的提示信息根据不同的浏览器有所不同,标准的信息类似 "确定要离开此页吗?"。该信息不能删除。
  • 可以自定义一些消息提示与标准信息一起显示在对话框。
<element onbeforeunload="myScript">
object.onbeforeunload=function(){myScript};
object.addEventListener("beforeunload", myScript);

vm.$on( event, callback )

参数:

  • {string | Array} event (数组只在 2.2.0+ 中支持)
  • {Function} callback

用法:

  • 监听当前实例上的自定义事件。事件可以由 vm.$emit 触发。
  • 回调函数会接收所有传入事件触发函数的额外参数。

示例:

vm.$on('test', function (msg) {
  console.log(msg)
})
vm.$emit('test', 'hi')
// => "hi"

步骤

第一步:创建方法在common.js下新建leaveConfirm方法并且默认暴露 export default{}

  • @param {Component} vm vue实例
  • @param {Function} fn 生效条件,返回布尔值
  • @param {String} tip 离开页面提示语
leaveConfirm(
    vm,
    fn = () => {
        return false;
    },
    tip = "当前页面数据未保存,确认离开?"
) {
    _leaveConfirmVm = vm;
    vm.$on("hook:updated", () => {
        window.onbeforeunload = function (event) {
            if (fn(vm)) {
                event = event || window.event;
                if (event) {
                    event.preventDefault();
                    event.returnValue = "关闭提示";
                }
                return "关闭提示";
            } else {
                return null;
            }
        };
    });
    //组件销毁后移出onbeforeunload事件
    vm.$on("hook:beforeDestroy", () => {
        window.onbeforeunload = null;
        router.beforeResolve = () => {};
    });
    //增加路由拦截,执行完next()后需要将beforeResolve重置
    router.beforeResolve((to, from, next) => {
        if (fn(_leaveConfirmVm)) {
            const answer = window.confirm(tip);
            answer ? next() : next(false);
        } else {
            next();
        }
    });
},

第二步:在main.js将其挂载在vue原型上(需要引入leaveConfirm方法)

import common from './utils'
Vue.prototype.$leaveConfirm = common.leaveConfirm

第三步:在vue组件中使用

this.$leaveConfirm(this,(vm)= >{
    return (
    	!vm.btnLoading &&
         JSON.stringify(vm.inirParams) !== JSON.stringfiy(vm.params)
    )
    //可自行设置判断条件
})

总结

这只是其中的一种实现方式,也可以结合一些ui插件(elementui等)做出更多的效果。如有不足之处,请留下你的意见。

posted @ 2022-03-24 00:19  Atrox493  阅读(3469)  评论(0编辑  收藏  举报