uniapp中同时触发@markertap和@tap事件如何解决?

在uniapp中,当我点击地图上的marker时,同时触发了@markertap@tap事件,导致重复执行逻辑。如何让这两个事件互不干扰,或者只触发其中一个事件?目前尝试用stopPropagation()无效,有没有其他解决方案?

2 回复

在uniapp中,同时触发@markertap@tap事件时,可以通过阻止事件冒泡来解决。在@markertap事件处理函数中使用e.stopPropagation(),或者在@tap事件中判断事件源,避免重复处理。


在uniapp中,当点击地图上的标记(marker)时,会同时触发@markertap@tap事件。这是因为@tap是地图的点击事件,而@markertap是标记的点击事件,两者属于不同层级。

解决方案

方案1:使用事件对象判断

@tap事件中通过事件对象判断是否点击了标记:

<map 
  @markertap="onMarkerTap" 
  @tap="onMapTap"
  style="width: 100%; height: 300px;"
  :markers="markers">
</map>
methods: {
  onMarkerTap(e) {
    console.log('点击了标记:', e.markerId)
    // 处理标记点击逻辑
  },
  
  onMapTap(e) {
    // 如果没有markerId,说明点击的是地图空白区域
    if (!e.markerId) {
      console.log('点击了地图空白区域')
      // 处理地图点击逻辑
    }
  }
}

方案2:使用定时器延迟处理

通过setTimeout让@tap事件延迟执行,在@markertap中取消@tap的执行:

data() {
  return {
    tapTimer: null
  }
},
methods: {
  onMarkerTap(e) {
    // 清除tap定时器
    clearTimeout(this.tapTimer)
    console.log('点击了标记:', e.markerId)
    // 处理标记点击逻辑
  },
  
  onMapTap(e) {
    // 设置定时器,延迟执行
    this.tapTimer = setTimeout(() => {
      if (!e.markerId) {
        console.log('点击了地图空白区域')
        // 处理地图点击逻辑
      }
    }, 100)
  }
}

方案3:使用标志变量

通过标志变量控制事件执行:

data() {
  return {
    isMarkerTapped: false
  }
},
methods: {
  onMarkerTap(e) {
    this.isMarkerTapped = true
    console.log('点击了标记:', e.markerId)
    
    // 处理标记点击逻辑
    
    // 重置标志
    setTimeout(() => {
      this.isMarkerTapped = false
    }, 50)
  },
  
  onMapTap(e) {
    if (!this.isMarkerTapped) {
      console.log('点击了地图空白区域')
      // 处理地图点击逻辑
    }
  }
}

推荐方案

方案1是最推荐的,因为它:

  • 代码简洁明了
  • 性能最佳
  • 无需额外的状态管理
  • 符合uniapp的事件机制

在实际开发中,根据具体需求选择合适的解决方案即可。

回到顶部