Vuejs - 事件委托和 v-for 上下文引用
Posted
技术标签:
【中文标题】Vuejs - 事件委托和 v-for 上下文引用【英文标题】:Vuejs - Event delegation and v-for context reference 【发布时间】:2017-10-10 18:47:58 【问题描述】:我正在使用以下 sn-p 来呈现列表:
<div @click.prevent="myhandler($event)"><!-- Delegated event handler-->
<div class="tasks" v-for="(task, subName) in step.tasks">
<button type="button">
task.caption
</button>
<span> task.callableName </span>
</div>
</div>
methods:
myhandler(e)
// Event target may be a button element.
let target = e.target;
// …
// Let's assume we know 'target' is a button element instance.
// I wish I could have access to the v-for item ("task") which is associated in some ways to the button that was clicked.
// let the_task_reference = ?;
…
有没有一种干净的方法可以让我到达与该按钮相关的v-for
范围特定任务?
谢谢。
【问题讨论】:
【参考方案1】:另一种方法是将任务的索引存储在按钮上。
<div class="tasks" v-for="(task, index) in step.tasks">
<button type="button" :data-index="index">
task.caption
</button>
<span> task.callableName </span>
</div>
并在您的处理程序中使用索引获取任务。
myhandler(evt)
const task = this.step.tasks[evt.target.dataset.index]
...
Example.
如果你有更强大的东西,比如id
,那就更好了。
不推荐
有一个隐藏属性 __vue__
添加到 Vue 和 Component 根元素中。如果你迭代一个组件,你将能够做一些事情like in this example。
我不推荐这种方法,因为它严重依赖 Vue 内部结构,可能会因版本而异,但它今天就存在。
【讨论】:
我就是这么想的。我可能会去,因为似乎没有其他整洁的选择。我会让这个问题再多活一天,并将您的答案视为解决方案。谢谢。【参考方案2】:最直接的解决方案是将事件处理程序放在与v-for
指令相同的div
上,然后传入task
变量:
<div
class="tasks"
v-for="(task, subName) in step.tasks"
@click.prevent="myhandler(task, $event)"
>
<button type="button"> task.caption </button>
<span> task.callableName </span>
</div>
如果您确实需要在父元素上使用事件处理程序,您可以通过组件属性跟踪单击的任务,并使用 v-for
指令向 div 添加额外的单击处理程序:
<div @click.prevent="myhandler($event)"
<div
class="tasks"
v-for="(task, subName) in step.tasks"
@click="clickedTask = task"
>
<button type="button"> task.caption </button>
<span> task.callableName </span>
</div>
</div>
您需要添加一个clickedTask
属性:
data()
return
clickedTask: null,
然后在处理程序中,您可以通过this.clickedTask
引用任务。
【讨论】:
谢谢,但我知道。正如我所提到的,我需要在这里使用事件委托。换句话说,我希望第一个共同祖先来处理事件,这意味着当我只能访问作为事件目标的按钮元素时,我需要一种方法来引用任务对象。 @Stphane 无法从其范围之外的事件直接访问task
变量。您需要设置一个额外的参考。查看我的更新
我认为 vue 实例上的一些隐藏属性会有所帮助,但似乎这样的事情不存在。我担心您的最终解决方案会导致过多的开销。首先,因为仍然会在每个 v-for div 元素上注册一个点击处理程序(我想首先避免),其次需要一个新的代理数据。我会深入研究,让你知道我最终得到了什么。再次感谢您。以上是关于Vuejs - 事件委托和 v-for 上下文引用的主要内容,如果未能解决你的问题,请参考以下文章
Vuejs v-for 根据某些条件添加标签属性或事件监听器