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
?
These two links helped me figure this out:
https://vuejs.org/v2/examples/modal.html
https://laracasts.com/discuss/channels/vue/passing-data-form-v-for-loop-to-modal-component
#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 :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With