Vue2中用$listeners重映射事件名避冲突是否可行?有无更优方案?
Vue2中Knob组件事件冲突的处理方案
这种通过$listeners重映射事件名的方式完全可行,而且是处理子组件事件冲突的常规操作——毕竟两个Knob都触发rotated事件,父组件根本分不清是谁触发的,重命名成move-knob-left和move-knob-right能清晰区分来源,逻辑上没问题。
至于更简洁的实现方案,给你两种思路:
方案一:直接在GameToolbar内监听并转发事件
不用依赖$listeners,直接在GameToolbar里监听两个Knob的rotated事件,手动触发带区分度的事件给上层父组件,逻辑更直观:
<template> <div class="game-toolbar"> <Knob @rotated="emitLeftKnobEvent" /> <Knob @rotated="emitRightKnobEvent" /> </div> </template> <script> export default { methods: { emitLeftKnobEvent(rotationData) { this.$emit('move-knob-left', rotationData) }, emitRightKnobEvent(rotationData) { this.$emit('move-knob-right', rotationData) } } } </script>
上层父组件的监听方式和你原来的完全一致,这种写法比用$listeners更直白,看代码就能一眼理清逻辑。
方案二:给Knob组件加标识属性,让它自己触发带后缀的事件
如果你的Knob组件是可复用的,可以给它加一个eventSuffix属性,让Knob根据这个后缀生成不同的事件名,这样GameToolbar的代码会更简洁:
首先修改Knob组件:
<script> export default { props: { eventSuffix: { type: String, default: '' } }, methods: { handleRotation(rotationValue) { // 这里是原来的旋转逻辑 const eventName = this.eventSuffix ? `rotated-${this.eventSuffix}` : 'rotated' this.$emit(eventName, rotationValue) } } } </script>
然后在GameToolbar里使用:
<template> <div class="game-toolbar"> <Knob eventSuffix="left" /> <Knob eventSuffix="right" /> </div> </template>
上层父组件直接监听@rotated-left和@rotated-right就可以了,这种方式把事件区分的逻辑下沉到了Knob组件,上层组件不用写转发逻辑,复用性更强。
内容的提问来源于stack exchange,提问作者DomonkosCs
相关产品推荐
相关产品推荐

