Home » vue » Vue2 modal in v-for list

Vue2 modal in v-for list

Posted by: admin November 26, 2021 Leave a comment

Questions:

I’m trying to implement a vue2 modal as described in the vue docs at https://vuejs.org/v2/examples/modal.html.

It looks something like this:

<tbody v-if="fields.length">
    <tr v-for="(item, index) in fields">
        <td>@{{ item.name }}</td>
        <td><input type="checkbox" id="checkbox" v-model="item.active"></td>
        <td>
            <button id="show-modal" @click="showModal = true">Show Modal</button>
        </td>
    </tr>
    <modal :item="item" v-if="showModal" @close="showModal = false">
        <h3 slot="header">Hello World</h3>
    </modal>
</tbody>


Vue.component('modal', {
    template: '#modal-template',
    data: function() {
        return {
            item: ''
        }
    }
});

While the button shows up and does pop up the modal, I get a warning that Property or method "item" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option., and when I inspect the modal component in the Vue dev tools, the item is still '', it’s not populated by the :item binding.

What’s the right way to pass the item object into the modal so we can use it in the window?

Answers:

If you’re passing item as a value from the parent to a child component, you cannot use data–you must use props instead!

Vue.component('modal', {
    template: '#modal-template',
    props: ['item'],
    data: function() {
        return {

        }
    }
});

###

There are 2 things:

  1. You don’t reference item in the data object instead you should reference it as a prop for the component props: ['item'].
  2. The modal is not inside the loop’s scope, which ends at the closing </tr> tag. You could change this so that the click action performs a method that takes the item and assigns it to a variable that is always passed in like a prop. This would be similar to how you are doing it now, you would just change showModal = true to openModal(item) then have a method that would set the appropriate 2 values. Something like this:

    openModal(item) {
      this.showModal = true;
      this.modalItem = item;
    }
    
    ...
    
    data: () => {
      modalItem: null
      ...
    }