背景: 1. 这几天遇到个小需求:用户填写表单未保存,点击其他按钮,提示是否保存。如果否,离开当前页面并进行下一步
  • 当产品提出这个需求后,我内心毫无波澜,心里想,这不是很简单吗~~~ 直接用 vue-router 的组件内守卫 beforeRouteLeave 不就行了。然而,还是太年轻了。所以,在这里总结下,给自己留个记录。
  • 项目简介:我们的项目是基于vue全家桶开发后打包静态文件和elector打包成app的项目。对于本次需求到的页面,布局如下:传统的布局。用户在内容区3填写表单后,点击1 2 区域,需要提示用户是否保存。

  • 刚开始我的开发想法,直接调用vue-router 的组件内守卫,离开时判断即可,然而,事情没有这莫简单~~ : beforeRouteLeave 只能在路由离开前“截住”路由的改变。
  • 而我们的项目,左边列表区2 和头部菜单 区域1 的点击都会修改 vuex的状态,导致区域三的基础数据发生改变,从而引发请求刷新内容区。

也就是说:beforeRouteLeave 不能达到想要的效果。 因为beforeRouteLeave无法阻止js触发的事件。想要阻止事件的进行,相信自然而然都能想到:捕获 与 冒泡。但是新的问题又来了。就算阻止了事件的进行,那需求里面的并进行下一步该怎么处理?

我的想法是:在阻止事件传播时,记录下事件的 event,当用户确认不保存取消,再继续让event的targrt来执行刚才的事件。

具体做法:

  1. 在vuex里面增加状态变量A,标识是否表单数据被修改
  2. 在区域1 2 的最外层,绑定函数,执行事件捕获,函数里面根据A来确定,是否阻止冒泡。如果点击了1 2 区域,进行下一步。
  3. 判断是否表单数据被修改,修改了则分发中央事件,传递参数event,让内容区自己处理提示弹框,待用户确认。

        verifyProjuctDataHandler(e){
         if(A){
           e.stopPropagation()
           console.log('分发点击其他区域事件');
           window.eventHub.$emit('clickOtherArea', e)
           return false
           }
       },

4.如果用户点击了取消,执行对应的操作,并执行需求并进行下一步
用分发的事件的event,获取到的点击坐标,并模拟操作。达到效果:模拟事件暂停并继续执行。

    // 模拟鼠标点击坐标(x,y)
   function clickPoint(x, y){
     var ev = new MouseEvent('click', {
         'view': window,
         'bubbles': true,
         'cancelable': true,
         'clientX': x,
         'clientY': y    });

     var el = document.elementFromPoint(x, y);

     el.dispatchEvent(ev);
   }

至此,需求基本开发完成。如果有大佬有更好的解决思路,欢迎留言~~~


丰子楷
4 声望0 粉丝