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 informati
While the accepted answer is great but the modal component has to be designed only for that specific data and it's not reusable.
Here is how I created a reusable modal regardless of data and style :
Modal Component:
<template>
<div v-if="visible" class="modal-container">
<!-- Modal content goes here -->
<slot></slot>
<button @click="close">close</button>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return {
visible : false
}
},
methods : {
show(index){
this.visible = true
},
close(){
this.visible = false
}
}
}
</script>
<style>
// general styles for modal
.modal-container{
}
<style/>
Usage In Parent Component:
<template>
<ul>
<li v-for="(item, index) in myList" :key="index">
<button @click="showModal(index)">Show Modal</button>
<modal :ref="'modal_' + index">
<!-- modal content goes here -->
<div>{{ item.title }}</div>
<div>{{ item.content }}</div>
</modal>
</li>
</ul>
</template>
<script>
import Modal from "./Modal";
export default {
data(){
return {
myList : [
{ title : "title1", content : "content1"},
{ title : "title2", content : "content2"},
]
}
},
components: {
Modal
},
methods: {
showModal(index) {
let modal_id = "modal_" + index;
this.$refs[modal_id][0].show(index);
}
}
};
</script>
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 :-)