0๐
Hereโs a working example:
https://codesandbox.io/s/nervous-dew-kjb4ts
Step 1
Make a modal โ see example.
We can use slots to put dynamic content, like other components in each instance of the modal, and named slots for multiple sections. We will control visibility in the outer component / the mixin.
<template>
<transition name="modal">
<div class="modal-header">
<slot name="header"> default header </slot>
</div>
<div class="modal-body">
<slot name="body"> default body </slot>
</div>
<slot name="footer">
Default Footer
<button class="modal-default-button" @click="$emit('close')">
๐ซ Close
</button>
</slot>
</transition>
</template>
<script>
export default {
name: "Modal",
};
</script>
<style scoped>
// See link above for full styles
</style>
Step 2
Create a mixin that all components containing a modal can extend from. Here weโll put methods for opening, closing and anything else you need. Create a data attribute to indicate modal state for use with v-if, then add two methods for opening and closing.
import Modal from "@/components/Modal";
export default {
components: {
Modal
},
data: () => ({
modalState: false
}),
methods: {
openModal() {
this.modalState = true;
},
closeModal() {
this.modalState = false;
},
},
};
Step 3
Create your components, that extend from the mixin, and use the modal component with whatever content you like.
You can trigger right-clicks using: @mouseup.right
<template>
<div class="example-component comp1">
<h2>Component 1</h2>
<button @contextmenu.prevent
@mouseup.right="openModal()"
@click="tryRightClick()">
Open Component 1 Modal
</button>
<Modal v-if="modalState" @close="closeModal()">
<template v-slot:header>๐ Component 1 Modal</template>
<template v-slot:body>
Lorem ipsum
</template>
</Modal>
</div>
</template>
<script>
import modalMixin from "@/mixins/component-modal-mixin";
export default {
mixins: [modalMixin],
};
</script>
Step 4
Finally, just import your components.
<template>
<div id="app">
<h3>StackOverflow Answer for Terbah Dorian</h3>
<i>Example of separate components opening separate modals</i>
<Component1 />
<Component2 />
<Component3 />
</div>
</template>
<script>
import Component1 from "@/components/Component1";
import Component2 from "@/components/Component2";
import Component3 from "@/components/Component3";
export default {
name: "App",
components: {
Component1,
Component2,
Component3,
},
};
</script>
Hope that helps ๐
If it did, then an upvote would be appreciated!
0๐
You can send a simple data to know which popup should be show to your client,
for example:
in App.vue setup() section you have this :
const popup = reactive({
type: "none",
data: "hello world"
});
const popupToggle = ref(false);
function showPopup(type, data){
popup.type = type;
popup.data = data;
popupToggle.value = true;
}
function closePopup(){
popup.type = "none";
popup.data = "empty";
popupToggle.value = false;
}
and provide your functions into your project with :
provide("popupFunctions", {showPopup, closePopup});
and inject provided functions in other child documents with :
const {showPopup, closePopup} = inject("popupFunctions");
now all you need is call the functions which named showPopup
and closePopup
to change popup
variable which you created before in your App.vue and check the popup
type to show the targeted component as a popup to your client
Something like this in <template> section in your App.vue :
<popup-component v-if="popupToggle">
<popup-msgbox v-if="popup.type === 'msgBox'" :popup-data="popup.data" />
<popup-formbox v-else-if="popup.type === 'formBox'" :popup-data="popup.data" />
<popup-errorbox v-else-if="popup.type === 'errBox'" :popup-data="popup.data" />
</popup-component>
of course you should import these components and other required things in your project as you know, and i just tried to clear the solve way for you.
I hope my answer be clear to you and help you solve your problem.
0๐
https://codesandbox.io/s/laughing-shape-18dnqq?file=/src/App.vue
I made a working sample to display dynamic popovers by hovering the buttons. You can use Slots in Vue components.
Hope this helps you.