DEV Community

Ali Ozzaim
Ali Ozzaim

Posted on • Edited on

Fixing vue-js-modal Library for Vue 3: A Guide to Restoring Modal Functionality

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

Enter fullscreen mode Exit fullscreen mode

Changes in PluginCore.js
Imports and Initialization:

Replace the existing imports and initialization with the following:


import { h, render, createVNode } from 'vue';

Enter fullscreen mode Exit fullscreen mode

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
    );
};

Enter fullscreen mode Exit fullscreen mode

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);
    }
};

Enter fullscreen mode Exit fullscreen mode

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" || {}
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
euvl profile image
Yev Vlasenko

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.