Is there a way in Vue.js for multiple parents to share the same child component?
I am looking to have multiple delete buttons trigger a single modal with different content.
For example:
myfile.html:
<table id="app" class="table table-striped table-sm table-responsive-md">
<thead>
<tr>
<th>Title</th>
<th></th>
</tr>
</thead>
<tbody>
<tr class="post">
<td>Test2</td>
<td>
<delete-confirm popup-title="Are you sure ?" popup-message="Message 1">
Delete
</delete-confirm>
</td>
</tr>
<tr class="post">
<td>Test article</td>
<td>
<delete-confirm popup-title="Are you sure ?" popup-message="Message 2">
Delete
</delete-confirm>
</td>
</tr>
</tbody>
</table>
app.js:
require('./bootstrap');
window.Vue = require('vue');
Vue.component('delete-confirm', require('./components/DeleteConfirm.vue'));
Vue.component('magnific-popup', require('./components/MagnificPopup.vue'));
const app = new Vue({
el: '#app'
});
components/DeleteConfirm.vue:
<template>
<span>
<button ref="button" @click="showConfirmation($event.target)" class="btn btn-danger">
<i class="fa fa-trash"></i> <slot></slot>
</button>
<magnific-popup v-on:click="click" ref="popup">
<h2 slot="title">{{ popupTitle }}</h2>
<p slot="content">{{ popupMessage }}</p>
</magnific-popup>
</span>
</template>
<script>
import $ from 'jquery';
export default {
props: ['popupTitle', 'popupMessage'],
methods: {
showConfirmation(target) {
this.$refs.popup.open(target);
},
click(type) {
this.$refs.popup.close();
if (type === 'confirm') {
$.ajax({
url: '404me',
type: 'DELETE',
}).then(() => { /* TODO */ }).catch(() => { /* TODO */ });
}
}
},
};
</script>
components/MagnificPopup.vue:
<template>
<div class="white-popup zoom-anim-dialog mfp-hide">
<div class="container bg-light col-8 mx-auto p-3 rounded">
<slot name="title"></slot>
<div class="popup-content">
<slot name="content"></slot>
</div>
<div class="popup-actions">
<button type="button" @click="sendYes" class="btn btn-primary">
Yes
</button>
<button type="button" @click="sendNo" class="btn btn-secondary">
No
</button>
</div>
</div>
</div>
</template>
<script>
import $ from 'jquery';
require('magnific-popup');
export default {
methods: {
sendYes() {
this.$emit('click', 'confirm');
},
sendNo() {
this.$emit('click', 'cancel');
},
close: function() {
$.magnificPopup.close();
},
open: function(trigger) {
$.magnificPopup.open({
items: {
src: this.$el,
},
midClick: true,
mainClass: 'my-mfp-zoom-in',
fixedContentPos: false,
fixedBgPos: true,
overflowY: 'auto',
closeBtnInside: true,
preloader: false,
removalDelay: 300,
});
},
}
};
</script>
<style lang="scss">
@import '~magnific-popup/src/css/main';
@import '../../css/magnific-popup.css';
</style>
Although it functions properly, one magnific-popup element is created per button component which is inefficient.
Here is the generated HTML code demonstrating the issue better.
It would be ideal not to have to declare a <magnific-popup>
in each file that uses the <button-delete>
component (e.g. in myfile.html).
Is there a method to include the popup component as a dependency so that it is added once to the DOM and can be reused later on?
What I want to achieve is something like this:
Only <delete-confirm>
elements declared in myfile.html, without <magnific-popup>
present.
Declare MagnificPopup
as a dependency of DeleteConfirm
so that whenever one or more <delete-confirm>
elements are used, a single <magnific-popup>
element is added to the DOM of myfile.html.