背景: 1. 这几天遇到个小需求:用户填写表单未保存,点击其他按钮,提示是否保存。如果否,离开当前页面并进行下一步
- 当产品提出这个需求后,我内心毫无波澜,心里想,这不是很简单吗~~~ 直接用 vue-router 的组件内守卫 beforeRouteLeave 不就行了。然而,还是太年轻了。所以,在这里总结下,给自己留个记录。
- 项目简介:我们的项目是基于vue全家桶开发后打包静态文件和elector打包成app的项目。对于本次需求到的页面,布局如下:传统的布局。用户在内容区3填写表单后,点击1 2 区域,需要提示用户是否保存。
- 刚开始我的开发想法,直接调用vue-router 的组件内守卫,离开时判断即可,然而,事情没有这莫简单~~ : beforeRouteLeave 只能在路由离开前“截住”路由的改变。
- 而我们的项目,左边列表区2 和头部菜单 区域1 的点击都会修改 vuex的状态,导致区域三的基础数据发生改变,从而引发请求刷新内容区。
也就是说:beforeRouteLeave 不能达到想要的效果。 因为beforeRouteLeave无法阻止js触发的事件。想要阻止事件的进行,相信自然而然都能想到:捕获 与 冒泡。但是新的问题又来了。就算阻止了事件的进行,那需求里面的并进行下一步该怎么处理?
我的想法是:在阻止事件传播时,记录下事件的 event,当用户确认不保存取消,再继续让event的targrt来执行刚才的事件。
具体做法:
- 在vuex里面增加状态变量A,标识是否表单数据被修改
- 在区域1 2 的最外层,绑定函数,执行事件捕获,函数里面根据A来确定,是否阻止冒泡。如果点击了1 2 区域,进行下一步。
判断是否表单数据被修改,修改了则分发中央事件,传递参数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);
}
至此,需求基本开发完成。如果有大佬有更好的解决思路,欢迎留言~~~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。