In one of my Vue 2 projects, I utilized the vue-js-modal library. However, after migrating the project from Vue 2 to Vue 3, the modal didn’t work properly. Despite extensive research, I couldn't find any documentation or discussions addressing this issue, which led me to write this article.
In this article, I will share the changes I made to adapt vue-js-modal for Vue 3. I hope you find these insights helpful!
First, please review the GitHub thread and apply the changes suggested here: https://github.com/euvl/vue-js-modal/issues/814
After following the suggestions from the GitHub thread, you might still encounter issues with the modal in your Vue 3 project. To fully resolve these problems, I made several changes to the PluginCore.js and Plugin.js files. Below, you'll find the details of these changes.
Changes in Plugin.js
Modify the plugin:
import Modal from './components/Modal.vue'
import Dialog from './components/Dialog.vue'
import PluginCore from './PluginCore'
const Plugin = {
install(app, options = {}) {
if (app.config.globalProperties.$modal) {
return
}
const plugin = PluginCore(options)
app.config.globalProperties.$modal = plugin
app.provide('$modal', plugin)
app.mixin({
mounted() {
if (this.$root === this) {
if (!plugin.context.root) {
plugin.setDynamicModalContainer(this)
}
}
}
})
/**
* Sets custom component name (if provided)
*/
app.component(plugin.context.componentName, Modal)
/**
* Registration of <Dialog/> component
*/
if (options.dialog) {
const componentName = options.dialogComponentName || 'VDialog'
app.component(componentName, Dialog)
}
}
}
export default Plugin
Changes in PluginCore.js
Imports and Initialization:
Replace the existing imports and initialization with the following:
import { h, render, createVNode } from 'vue';
Show Dynamic Modal:
Update the logic for showing dynamic modals:
const showDynamicModal = (
component,
componentProps,
componentSlots,
modalProps = componentSlots || {},
modalEvents
) => {
const container = context.root?.__modalContainer;
const defaults = options.dynamicDefaults || {};
if (!container) {
console.warn('Modal container not found. Make sure the dynamic modal container is set.');
return;
}
container.add(
component,
componentProps,
componentSlots,
{ ...defaults, ...modalProps },
modalEvents
);
};
Set Dynamic Modal Container:
Modify the function responsible for setting the modal container:
const setDynamicModalContainer = (root) => {
context.root = root;
if (!root) {
console.warn('Root component is undefined. Make sure the root instance is passed correctly.');
return;
}
const element = createDivInBody();
const vnode = createVNode(ModalsContainer);
vnode.appContext = root.$.appContext;
try {
return render(vnode, element);
} catch (error) {
console.error('Error rendering vnode:', error);
}
};
Final Changes in ModalsContainer.vue
As part of the migration to Vue 3, it was necessary to make a specific adjustment in the ModalsContainer.vue component.
Updating Event Listeners:
In the ModalsContainer.vue file, remove the existing v-on="$listeners" directive and replace it with:
v-on="modal.componentListeners" || {}
This change should be made at line number 13.
By making these adjustments, you should be able to successfully migrate the vue-js-modal library to work seamlessly with Vue 3. I hope these steps help you resolve any remaining issues with your modals! If you need further assistance, please don't hesitate to ask in the comments section. Additionally, I would appreciate any feedback or insights you have, so feel free to leave your comments below
https://www.aliozzaim.com
https://github.com/Aliozzaim/vue-js-modal updated repo
references
https://github.com/euvl/vue-js-modal/issues/814
https://github.com/euvl/vue-js-modal
Top comments (1)
Hey Ali, great stuff, do you think you could make a pull request for vue-js-modal? I'm not using vue for quite a few years but will be great to get that into the package.
Thanks.