Skip to content

Commit 7b99e6a

Browse files
committed
Patch from euvl#814
1 parent 2dcc679 commit 7b99e6a

File tree

5 files changed

+37
-21
lines changed

5 files changed

+37
-21
lines changed

src/Plugin.js

+10-9
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ import Dialog from './components/Dialog.vue'
33
import PluginCore from './PluginCore'
44

55
const Plugin = {
6-
install(Vue, options = {}) {
7-
if (Vue.prototype.$modal) {
6+
install(app, options = {}) {
7+
if (app.config.globalProperties.$modal) {
88
return
99
}
1010

11-
const plugin = new PluginCore(Vue, options)
11+
const plugin = PluginCore(app, options)
1212

13-
Object.defineProperty(Vue.prototype, '$modal', {
13+
Object.defineProperty(app.config.globalProperties, '$modal', {
1414
get: function() {
1515
/**
1616
* The "this" scope is the scope of the component that calls this.$modal
@@ -19,29 +19,30 @@ const Plugin = {
1919
/**
2020
* The this.$modal can be called only from inside the vue components so this check is not really needed...
2121
*/
22-
if (caller instanceof Vue) {
22+
// if (caller instanceof app) {
2323
const root = caller.$root
2424

2525
if (!plugin.context.root) {
26-
plugin.setDynamicModalContainer(root)
26+
plugin.setDynamicModalContainer(root, app)
2727
}
28-
}
28+
// }
2929

3030
return plugin
3131
}
3232
})
33+
app.provide('$modal', plugin)
3334

3435
/**
3536
* Sets custom component name (if provided)
3637
*/
37-
Vue.component(plugin.context.componentName, Modal)
38+
app.component(plugin.context.componentName, Modal)
3839

3940
/**
4041
* Registration of <Dialog/> component
4142
*/
4243
if (options.dialog) {
4344
const componentName = options.dialogComponentName || 'VDialog';
44-
Vue.component(componentName, Dialog);
45+
app.component(componentName, Dialog);
4546
}
4647
}
4748
}

src/PluginCore.js

+19-9
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
import { UNSUPPORTED_ARGUMENT_ERROR } from './utils/errors'
22
import { createDivInBody } from './utils'
33
import ModalsContainer from './components/ModalsContainer.vue'
4-
5-
const PluginCore = (Vue, options = {}) => {
6-
const subscription = new Vue()
4+
import emitter from 'tiny-emitter/instance'
5+
import {createVNode, render} from 'vue'
6+
7+
const PluginCore = (app, options = {}) => {
8+
const subscription = {
9+
$on: (...args) => emitter.on(...args),
10+
$once: (...args) => emitter.once(...args),
11+
$off: (...args) => emitter.off(...args),
12+
$emit: (...args) => emitter.emit(...args),
13+
}
714

815
const context = {
916
root: null,
1017
componentName: options.componentName || 'Modal'
1118
}
19+
subscription.$on('set-modal-container', container => {
20+
context.root.__modalContainer = container
21+
})
1222

1323
const showStaticModal = (name, params) => {
1424
subscription.$emit('toggle', name, true, params)
@@ -37,17 +47,17 @@ const PluginCore = (Vue, options = {}) => {
3747
* Creates a container for modals in the root Vue component.
3848
*
3949
* @param {Vue} parent
50+
* @param {Vue} app
4051
*/
41-
const setDynamicModalContainer = parent => {
52+
const setDynamicModalContainer = ((parent, app) => {
4253
context.root = parent
4354

4455
const element = createDivInBody()
4556

46-
new Vue({
47-
parent,
48-
render: h => h(ModalsContainer)
49-
}).$mount(element)
50-
}
57+
const vnode = createVNode(ModalsContainer)
58+
vnode.appContext = app._context
59+
render(vnode, element)
60+
})
5161

5262
const show = (...args) => {
5363
const [modal] = args

src/components/Dialog.vue

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
:key="index"
3232
v-html="button.title"
3333
@click.stop="click(index, $event)"
34-
>{{ button.title }}</button>
34+
/>
3535
</div>
3636
<div v-else class="vue-dialog-buttons-none" />
3737
</component>
@@ -52,6 +52,7 @@ export default {
5252
type: String
5353
}
5454
},
55+
inject: ['$modal'],
5556
data() {
5657
return {
5758
params: {}

src/components/Modal.vue

+5-2
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ const TransitionState = {
7777
7878
export default {
7979
name: 'VueJsModal',
80+
inject: ['$modal'],
8081
props: {
8182
name: {
8283
required: true,
@@ -263,7 +264,7 @@ export default {
263264
/**
264265
* Removes global listeners
265266
*/
266-
beforeDestroy() {
267+
beforeUnmount() {
267268
this.$modal.subscription.$off('toggle', this.onToggle)
268269
269270
window.removeEventListener('resize', this.onWindowResize)
@@ -498,7 +499,9 @@ export default {
498499
499500
beforeModalTransitionLeave() {
500501
this.modalTransitionState = TransitionState.Leaving
501-
this.resizeObserver.unobserve(this.$refs.modal)
502+
if (this.$refs.modal) {
503+
this.resizeObserver.unobserve(this.$refs.modal)
504+
}
502505
503506
if (this.$focusTrap.enabled()) {
504507
this.$focusTrap.disable()

src/components/ModalsContainer.vue

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export default {
4040
* Register ModalContainer so that it was availiable inside the plugin
4141
*/
4242
this.$root.__modalContainer = this
43+
this.$modal.subscription.$emit('set-modal-container', this)
4344
},
4445
mounted() {
4546
this.$modal.subscription.$on('hide-all', () => {

0 commit comments

Comments
 (0)