diff --git a/README.md b/README.md index 176a30fe..c618ae10 100644 --- a/README.md +++ b/README.md @@ -206,6 +206,25 @@ this.$modal.show({ }) ``` +If using the `injectModalsContainer` flag, the first mounted Vue instance without parents will be treated as the application root. This is only important to keep in mind if more than one root Vue instance is being used, which is unlikely. But if that's the case, the root to use can be indicated with the `root` parameter when invoking dynamic modals or modifying this plugin's `rootInstance` attribute: + +```javascript +import App from './App.vue' +import VModal from 'vue-js-modal' + +const app1 = new Vue({ + el: '#app-1', + render: h => h(App) +}) + +const app2 = new Vue({ + el: '#app-2', + render: h => h(App) +}) + +VModal.rootInstance = app2 +``` + For more examples please take a look at [vue-js-modal.yev.io](http://vue-js-modal.yev.io). **Note:** keep in mind that there are some limitations for using dynamic modals. If you need full functionality then use ordinary modal instead. @@ -257,6 +276,7 @@ There is also a ssr build with css file extracted. Take a look in /dist folder. | maxHeight | false | Number (px) | Infinity | The maximum height of the modal (if the value is greater than window height, window height will be used instead | | pivotX | false | Number (0 - 1.0) | 0.5 | Horizontal position in %, default is 0.5 (meaning that modal box will be in the middle (50% from left) of the window | | pivotY | false | Number (0 - 1.0) | 0.5 | Vertical position in %, default is 0.5 (meaning that modal box will be in the middle (50% from top) of the window | +| root | false | Vue instance | null | Root instance to obtain modal container from. This property is only necessary when using dynamic modals with more than one root instance, which is uncommon | ### Events diff --git a/src/ModalsContainer.vue b/src/ModalsContainer.vue index 48481718..a4621784 100644 --- a/src/ModalsContainer.vue +++ b/src/ModalsContainer.vue @@ -25,7 +25,7 @@ export default { } }, created () { - this.$modal._setDynamicContainer(this) + this.$root._dynamicContainer = this }, methods: { add (modal, params, config, events) { diff --git a/src/index.js b/src/index.js index ca260cab..c7908854 100644 --- a/src/index.js +++ b/src/index.js @@ -15,23 +15,26 @@ const Plugin = { this.installed = true this.event = new Vue() - this.dynamicContainer = null + this.rootInstance = null this.componentName = options.componentName || defaultComponentName /** * Plugin API */ Vue.prototype.$modal = { - _setDynamicContainer (dynamicContainer) { - Plugin.dynamicContainer = dynamicContainer - }, show (modal, paramsOrProps, params, events = {}) { if (typeof modal === 'string') { Plugin.event.$emit('toggle', modal, true, paramsOrProps) } else { - if (Plugin.dynamicContainer === null) { - console.warn('[vue-js-modal] In order to render dynamic modals, a component must be present on the page') + let root = Plugin.rootInstance + if (params && params.root) { + root = params.root + } + + const dynamicContainer = getModalsContainer(Vue, options, root) + if (dynamicContainer) { + dynamicContainer.add(modal, paramsOrProps, params, events) } else { - Plugin.dynamicContainer.add(modal, paramsOrProps, params, events) + console.warn('[vue-js-modal] In order to render dynamic modals, a component must be present on the page') } } }, @@ -57,15 +60,29 @@ const Plugin = { * Registration of component */ if (options.dynamic) { - if (options.injectModalsContainer) { - const modalsContainer = document.createElement('div') - document.body.appendChild(modalsContainer) - new Vue({ render: h => h(ModalsContainer) }).$mount(modalsContainer) - } else { - Vue.component('modals-container', ModalsContainer) - } + Vue.component('modals-container', ModalsContainer) + Vue.mixin({ + beforeMount () { + if (Plugin.rootInstance === null) { + Plugin.rootInstance = this.$root + } + } + }) } } } +function getModalsContainer (Vue, options, root) { + if (!root._dynamicContainer && options.injectModalsContainer) { + const modalsContainer = document.createElement('div') + document.body.appendChild(modalsContainer) + new Vue({ + parent: root, + render: h => h(ModalsContainer) + }).$mount(modalsContainer) + } + + return root._dynamicContainer +} + export default Plugin diff --git a/types/index.d.ts b/types/index.d.ts index 19c55ab2..7d323fa9 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1,6 +1,8 @@ import Vue, { PluginObject, ComponentOptions } from "vue"; -declare const VueJSModal: PluginObject; +declare const VueJSModal: PluginObject & { + rootInstance?: Vue +}; export default VueJSModal; export declare interface VueJSModalOptions {