Search code examples
vuejs2v-for

Vuejs - Event delegation and v-for context reference


I'm using the following snippet to render a list:

<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 = ?;
    }…

Is there a clean way so that I could reach the v-for scope specific task related to that button?
Thank you.


Solution

  • An alternative would be to store the index of the task on the button.

    <div class="tasks" v-for="(task, index) in step.tasks">
        <button type="button" :data-index="index">
            {{ task.caption }}
        </button>
        <span> {{ task.callableName }} </span>
    </div>
    

    And in your handler get the task using the index.

    myhandler(evt){
      const task = this.step.tasks[evt.target.dataset.index]
      ...
    }
    

    Example.

    If you had something stronger like an id, that would be even better.

    Not Recommended

    There is a hidden property, __vue__ that is added to Vue and Component root elements. Were you to iterate over a component, you would be able to do something like in this example.

    I wouldn't recommend that approach because it relies heavily on Vue internals that could change from version to version, but it's there today.