首页 > 解决方案 > Vue 模板:如何自动将自定义属性添加到具有 v-on:click 指令的元素

问题描述

我们正在使用单个文件 vue 组件,并且在 mousemove 事件处理程序中,我们希望能够检测目标元素是否可点击。

在我们的 Vue 模板中,我们使用 v-on 指令:v-on:click="someCallback".

不幸的是,似乎没有一种简单的方法可以判断给定元素是否注册了事件侦听器(即通过 v-on 指令)。

为此,我们希望使用 v-on:click 指令为这些元素添加自定义属性 - 即“可点击”。但这应该自动发生。

因此,我们必须要么将 Vue 自己的“on”指令包装到自定义指令中,要么以某种方式挂钩到 Vue 的渲染周期——但这似乎不是很直接:在 Vue 实例或 Vue 组件上找不到指令目的。

我们尝试过的:

希望任何人都对如何使用 v-on:click 指令自动完成向元素添加自定义属性有一个很好的想法。

谢谢!

编辑:
所以我们的模板中有 ie <div id="x" @click="someMethod" /> 。但是我们想自动添加一个自定义属性(我们不想为所有万亿情况手动添加它): <div id="x" clickable @click="someMethod" /> 然后在 addEventListener('mousemove', handler) 的事件处理程序中,我们将检查这个属性:if (e.target.hasAttribute('clickable')) 但是任何其他方式完成这一点(因此能够在 mousemove 的处理程序内部判断元素是否可点击)也很好。

标签: javascriptvue.jsvuejs2event-handling

解决方案


您可以创建一个容器组件并将其导入所有其他 vue 组件,确保它是模板中的第一个组件,例如:

<template>
  <v-container>
    // your template here
  </v-container>
</template>

<script>
// Obviously replace the path and point to your location of the component
import ComponentContainer from './common/ComponentContainer.vue'
export default {
  name: 'MyClientComponent',
  components: {
    'v-container': ComponentContainer
  }
}
</script>

这是寻找点击事件并添加可点击类的容器组件:

<template>
  <div class="component-container">
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: 'ComponentContainer',
  mounted() {
    this.$slots.default.forEach(vn => {
      this.addClickableClassNames(vn);
    });
  },
  methods: {
    addClickableClassNames(vnode) {
      if (vnode) {
        let data = vnode.data;
        if (data && data.on) {
          // Check for click events and add a
          // clickable class if one exists
          if (data.on.click && vnode.elm && vnode.elm.classList) {
              vnode.elm.classList.add('clickable');
          }
        }
        // Now recursively check children
        if (vnode.children) {
          vnode.children.forEach(vn => {
            this.addClickableClassNames(vn);
          });
        }
      }
    }
  }
}
</script>

这行得通,但我不想评论大型 dom 的性能。您和其他开发人员需要记住导入所有组件,这并不理想。但是,它是一个解决方案,可能会为您提供有关改进和提高可扩展性的其他想法。


推荐阅读