javascript - Vue 模板:如何自动将自定义属性添加到具有 v-on:click 指令的元素
问题描述
我们正在使用单个文件 vue 组件,并且在 mousemove 事件处理程序中,我们希望能够检测目标元素是否可点击。
在我们的 Vue 模板中,我们使用 v-on 指令:v-on:click="someCallback"
.
不幸的是,似乎没有一种简单的方法可以判断给定元素是否注册了事件侦听器(即通过 v-on 指令)。
为此,我们希望使用 v-on:click 指令为这些元素添加自定义属性 - 即“可点击”。但这应该自动发生。
因此,我们必须要么将 Vue 自己的“on”指令包装到自定义指令中,要么以某种方式挂钩到 Vue 的渲染周期——但这似乎不是很直接:在 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 的处理程序内部判断元素是否可点击)也很好。
解决方案
您可以创建一个容器组件并将其导入所有其他 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 的性能。您和其他开发人员需要记住导入所有组件,这并不理想。但是,它是一个解决方案,可能会为您提供有关改进和提高可扩展性的其他想法。
推荐阅读
- sql - 在两个表中查询 Postgres
- anaconda - 将 Conda 环境移动到无法访问 Internet 的计算机
- css - 我可以在 NativeScript 应用程序的深色模式下使用白色背景吗?
- javascript - 如何通过单击状态从 FlatList 中一一删除项目
- powershell - 使用 Mailkit 和 Powershell 在 Imap 文件夹中搜索未读电子邮件
- google-cloud-platform - 谷歌云功能仪表板不工作
- javascript - 绑定到表单的进度条
- php - 如何在 DDEV-Local 的 Web 容器中安装像 mcrypt 这样的 pecl 扩展?
- python - AWS Lambda:s3 文件的唯一密钥生成器
- java - NoSuchBeanDefinitionException:没有“XInterceptor”类型的合格 bean