如何为vue-draggable添加带修饰符点击事件且不触发choose事件
问题描述
需求为在<draggable>组件的子元素上实现特殊点击逻辑:
- 仅当按下
alt或ctrl修饰键时,才触发子组件绑定的点击处理函数 - 触发上述带修饰键的点击时,不能触发draggable组件绑定的
choose事件
初始实现代码:
<draggable @choose="chooseEvent"> <child-element @click.native.alt.exact.stop="toggleProblem" @click.native.ctrl.exact.stop="toggleProblem" /> <!-- 其他draggable子项 --> </draggable>
该实现存在异常:按下对应修饰键点击时,toggleProblem可以正常执行,但chooseEvent始终会被触发。尝试过给choose事件添加.exact修饰符、给点击事件添加.stop/.prevent修饰符,均未解决问题。
根本原因
点击事件上的.stop修饰符仅能阻止原生DOM事件的冒泡传播,而Vue.Draggable(底层依赖SortableJS)的choose事件是库内部自行监听原生事件后封装触发的,触发时机早于事件冒泡阶段的拦截逻辑,单纯在子元素上阻止事件冒泡或默认行为,无法阻断库内部对choose事件的触发判定。
修复方案
不需要在事件冒泡阶段做拦截,直接在chooseEvent处理函数内部做修饰键判定即可:
- 保留子元素上原有的带修饰符的点击事件绑定
- choose事件触发时,先判断当前事件是否按下了
alt/ctrl键,如果是则直接终止函数执行,不运行后续拖拽选择逻辑 - 未按下修饰键时,正常执行choose事件原有逻辑
修复后代码:
<draggable @choose="chooseEvent"> <child-element @click.native.alt.exact.stop="toggleProblem" @click.native.ctrl.exact.stop="toggleProblem" /> <!-- 其他draggable子项 --> </draggable>
methods: { chooseEvent(evt) { // 检测到修饰键按下时直接返回,不触发拖拽选择逻辑 if (evt.originalEvent.altKey || evt.originalEvent.ctrlKey) { return false } // 此处写choose事件原有业务逻辑 }, toggleProblem() { // 此处写带修饰键点击的业务逻辑 } }
注意:Vue.Draggable回调参数中的原生事件对象存放在
originalEvent字段下,直接读取evt.altKey无法拿到正确值。
内容的提问来源于stack exchange,提问作者patrickdavey
相关产品推荐
相关产品推荐

