In my vue.js app, I need to display a list of items which the user can click.
When clicked, each of these items should then fire a modal, containing additional information about the item that the user just clicked.
What I have so far in my Items.vue
component is:
<template> <div id="content"> <li v-for="item in items" class="list-item pa2 ba"> <div class="f5 pt2 pb2"> <span>{{item.name}}</span> </div> </li> </div> </template> <script> import Items from '@/api/items'; export default { name: 'items', asyncComputed: { items: { async get() { const items = await Items.getAll(); return items.data; }, default: [] } }, components: {} } </script>
Now, I could simply add a modal component to the v-for
loop, thus creating one modal for each item, but this does not seem ideal if, for example, I have a list of thousands of items.
This led me to believe that the modal should probably be placed at the root of the app (in my case App.vue
), like this:
<template> <div id="app"> <modal></modal> <router-view></router-view> </div> </template> <script> export default { name: 'app' } </script>
and then somehow fired with custom data whenever I needed it.
However, I’m not sure how to proceed. How do I fire this modal with custom information from inside the v-for
loop, which is in a child component relative to App.vue
?
Advertisement
Answer
These two links helped me figure this out:
#In your Parent Component You don’t have to create a modal for each item within the v-for loop, simply include the modal-component at the beginning of your parent and then work with v-if=”…” and props.
<template> <div> <modal v-if="modalVisible" @close="modalVisible = false" :data="modalData"/> <div v-for="item in items"> <button type="button" @click="openModal(item)">Open Modal</button> </div> </div> </template>
and then in your script:
import modal from './Modal' export default { components: { modal }, data() { return { modalVisible: false, modalData: null } }, methods: { openModal(data) { this.modalData = data this.modalVisible = true }, }
#In your child (modal) component In your modal you can now do the following:
Template:
<template> {{ data.foo }} <button @click="$emit('close')">Cancel</button> </template>
Script
<script> export default { props: ['user'] }; </script>
Hope that helps 🙂