Closing the modal from withhin a slotted component on dynamic modals
I have this dynamic component, using a HOC and passing its content as its own component in the default slot.
However, I want to be able to close the modal by clicking a button within the AddTask component. I am able to emit the "confirm" event, but this way I am unable to pass the close function to close the modal, so I need to use $vfm.hideAll() as a workaround.
this.$vfm.show({
component: CustomModal,
slots: {
default: {
component: AddTask,
on: {
confirm() {
console.log("confirm");
$vfm.hideAll();
},
},
},
},
});
My question is: What would be the intended way to go about this?
Maybe this way:
use v-slot="{ close }"?
CustomModal.vue
<template>
<vue-final-modal v-slot="{ close }">
<div class="modal__action">
<slot @close="close"></slot>
</div>
</vue-final-mode>
</template>
...
AddTask.vue
<template>
<base-modal>
<template v-slot:action>
<button @click="confirm(close)">ОК</button>
</template>
</button>
<template>
...
<script>
export default {
...
methods: {
confirm(close) {
this.$emit('add-task-confirm', close);
},
...
}
</script>
and then call this.$vfm.show
this.$vfm.show({
component: CustomModal,
slots: {
default: {
component: AddTask,
on: {
addTaskConfirm(close) {
console.log("confirm");
close.onClose(); // !!!! another name of method
},
},
},
},
});
another way is using name of modal. Example:
onSomeEvent() {
const modalName= 'myAwesomeModal';
const $vfm = this.$vfm; // 'this' not defined on events like 'myAwesomeCmpConfirm'
this.$vfm.show({
component: BaseModal, // your modal with slot 'content' and props 'name'
bind: {
'name': modalName,
},
slots: {
'content': {
component: MyAwesomeCmp, // your cmp with emits
on: {
myAwesomeCmpConfirm(succes) {
if (succes) $vfm.hide(modalName); // or $vfm.hideAll(); if you need
},
myAwesomeCmpCancel() {
$vfm.hide(modalName);
},
},
},
},
});
Borrowing the example from my PR here The approach is using symbol id that can be identified later and hide the modal by setting the value
import PopupInfo from './PopupInfo';
const modalId = Symbol('myModal')
$vfm.show({
id: modalId,
component: DummyModal,
bind: {
title: 'My Awesome Modal',
},
on: {
closeTheModal: () => {
const modal = getModalComponent(modalId) // getting the dynamic modal
if (modal) {
(modal as any).value = false // closing the specific dynamic modal
}
}
}
});
const getModalComponent = (modalId: symbol): any | null => {
let foundModal = null;
for (const modal of $vfm.dynamicModals) {
if (modal.id === modalId) {
foundModal = modal;
break;
}
}
return foundModal;
};
PS: this example is using typescript, you may doing small adjustment for the JS version
Please try to use name props to hide the dynamic modal
this.$vfm.show({
component: CustomModal,
bind: {
name: 'UniqModalName'
},
slots: {
default: {
component: AddTask,
on: {
confirm() {
console.log("confirm");
$vfm.hide('UniqModalName');
},
},
},
},
});