You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3中如何为多元素添加双击事件(无需使用@dblclick)

解决方案

方法1:事件委托(推荐,符合Vue数据驱动思想)

在父容器(如ContentListItem的<tr>)上绑定一次双击事件,利用事件冒泡判断触发源是否为目标元素,无需给每个元素单独绑定事件。

修改ContentListItem组件:

<tr @dblclick="handleDblClick">
  <td>{{ index + 1 }}</td>
  <td>
    <input 
      type="checkbox"
      class="none-dblclick"
    />
  </td>
  <td>
    <span>
      <svg class="none-dblclick">
        <path ... />
      </svg>
    </span>
  </td>
  <td>{{ content.name }}</td>
</tr>

组件setup中定义处理函数:

import { defineProps } from 'vue'

export default {
  props: ['content', 'index'],
  setup() {
    const handleDblClick = (e) => {
      // 检查点击目标或其父元素是否包含目标类名
      const target = e.target.closest('.none-dblclick')
      if (target) {
        // 双击逻辑
        console.log('双击目标元素', target)
        // 可根据元素类型区分处理
        if (target.tagName === 'INPUT') {
          // 复选框双击逻辑
        } else if (target.tagName === 'SVG') {
          // 收藏图标双击逻辑
        }
      }
    }

    return { handleDblClick }
  }
}

方法2:自定义指令(复用性强)

注册全局或局部自定义指令,给需要绑定双击事件的元素添加指令即可,无需重复编写事件绑定逻辑。

局部注册(ContentListItem组件内)

<script setup>
import { defineProps, directive } from 'vue'

// 定义自定义指令
const vDblclickAction = directive('dblclick-action', {
  mounted(el) {
    const handler = () => {
      // 双击逻辑
      console.log('双击触发', el)
      // 可根据元素类型做区分处理
    }
    el.addEventListener('dblclick', handler)
    // 存储handler用于解绑,避免内存泄漏
    el._dblclickHandler = handler
  },
  unmounted(el) {
    el.removeEventListener('dblclick', el._dblclickHandler)
  }
})

const props = defineProps(['content', 'index'])
</script>

<template>
<tr>
  <td>{{ index + 1 }}</td>
  <td>
    <input 
      type="checkbox"
      v-dblclick-action
    />
  </td>
  <td>
    <span>
      <svg v-dblclick-action>
        <path ... />
      </svg>
    </span>
  </td>
  <td>{{ content.name }}</td>
</tr>
</template>

全局注册(main.js中)

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)
app.directive('dblclick-action', {
  mounted(el) {
    const handler = () => {
      // 双击逻辑
      console.log('全局指令双击触发')
    }
    el.addEventListener('dblclick', handler)
    el._dblclickHandler = handler
  },
  unmounted(el) {
    el.removeEventListener('dblclick', el._dblclickHandler)
  }
})

app.mount('#app')

注册后,任意组件内直接使用v-dblclick-action即可。

方法3:Ref结合生命周期(谨慎使用,需遵循DOM操作规范)

若坚持使用类名选择器,可在组件onMounted钩子中获取元素绑定事件,同时在onUnmounted中解绑,避免内存泄漏。

<script setup>
import { defineProps, onMounted, onUnmounted, ref } from 'vue'

const props = defineProps(['content', 'index'])
const listItemRef = ref(null)
let handlers = []

onMounted(() => {
  if (listItemRef.value) {
    const elements = listItemRef.value.querySelectorAll('.none-dblclick')
    handlers = Array.from(elements).map(el => {
      const handler = () => {
        // 双击逻辑
        console.log('双击元素', el)
      }
      el.addEventListener('dblclick', handler)
      return { el, handler }
    })
  }
})

onUnmounted(() => {
  handlers.forEach(({ el, handler }) => {
    el.removeEventListener('dblclick', handler)
  })
})
</script>

<template>
<tr ref="listItemRef">
  <td>{{ index + 1 }}</td>
  <td>
    <input 
      type="checkbox"
      class="none-dblclick"
    />
  </td>
  <td>
    <span>
      <svg class="none-dblclick">
        <path ... />
      </svg>
    </span>
  </td>
  <td>{{ content.name }}</td>
</tr>
</template>

内容的提问来源于stack exchange,提问作者ACS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 08:09:51