diff --git a/src/plugin/constants.ts b/src/plugin/constants.ts index b4064096..acfa84a7 100644 --- a/src/plugin/constants.ts +++ b/src/plugin/constants.ts @@ -1,4 +1,5 @@ // constants +export const DIRECTIVE_ATTRIBUTE_KEY = '__VUEJS_DIALOG__' export const DIALOG_TYPES = { ALERT: 'alert', // ex: Congrats! record created CONFIRM: 'confirm', // ex: Please confirm delete diff --git a/src/plugin/directive.dialog.ts b/src/plugin/directive.dialog.ts index f45ab018..eee82736 100644 --- a/src/plugin/directive.dialog.ts +++ b/src/plugin/directive.dialog.ts @@ -1,17 +1,15 @@ -// Directives - import { noop, clickNode, cloneObj } from './utilities' -import { CONFIRM_TYPES } from './constants' +import {CONFIRM_TYPES, DIRECTIVE_ATTRIBUTE_KEY} from './constants' + const DirectiveDialog = function (app) { Object.defineProperties(this, { - Vue: { get: () => app }, - confirmDefinition: { - get: this.defineConfirm - } + app: { get: () => app }, }) } +DirectiveDialog.prototype.shouldIgnoreClick = false + DirectiveDialog.prototype.getConfirmMessage = function (binding) { if (binding.value && binding.value.message) { return binding.value.message @@ -40,15 +38,9 @@ DirectiveDialog.prototype.getThenCallback = function (binding, el) { // If we got here, it means the default action is to be executed // We'll then stop the loader if it's enabled and close the dialog dialog.loading && dialog.close() - - // Unbind to allow original event - el.removeEventListener('click', el.VuejsDialog.clickHandler, true) - - // Trigger original event + this.shouldIgnoreClick = true clickNode(el) - - // Re-bind listener - el.addEventListener('click', el.VuejsDialog.clickHandler, true) + this.shouldIgnoreClick = false } } } @@ -61,6 +53,7 @@ DirectiveDialog.prototype.getCatchCallback = function (binding) { } DirectiveDialog.prototype.clickHandler = function (event, el, binding) { + if (this.shouldIgnoreClick) return event.preventDefault() event.stopImmediatePropagation() @@ -69,7 +62,7 @@ DirectiveDialog.prototype.clickHandler = function (event, el, binding) { const thenCallback = this.getThenCallback(binding, el) const catchCallback = this.getCatchCallback(binding) - this.Vue.dialog + this.app.config.globalProperties.$dialog .confirm(confirmMessage, options) .then(thenCallback) .catch(catchCallback) @@ -77,18 +70,18 @@ DirectiveDialog.prototype.clickHandler = function (event, el, binding) { DirectiveDialog.prototype.defineConfirm = function () { type BindFn = (el: unknown, binding: unknown) => void - const DirectiveDefinition: {bind: BindFn, unbind: BindFn} = {} - - DirectiveDefinition.bind = (el, binding) => { - el.VuejsDialog = el.VuejsDialog || {} + const DirectiveDefinition: {mounted: BindFn, unmounted: BindFn} = { + mounted: (el, binding) => { + el[DIRECTIVE_ATTRIBUTE_KEY] = el[DIRECTIVE_ATTRIBUTE_KEY] || {} - el.VuejsDialog.clickHandler = event => this.clickHandler(event, el, binding) + el[DIRECTIVE_ATTRIBUTE_KEY].clickHandler = event => this.clickHandler(event, el, binding) - el.addEventListener('click', el.VuejsDialog.clickHandler, true) - } - - DirectiveDefinition.unbind = (el) => { - el.removeEventListener('click', el.VuejsDialog.clickHandler, true) + el.addEventListener('click', el[DIRECTIVE_ATTRIBUTE_KEY].clickHandler, true) + }, + unmounted(el) { + el.removeEventListener('click', el[DIRECTIVE_ATTRIBUTE_KEY].clickHandler, true) + delete el[DIRECTIVE_ATTRIBUTE_KEY] + } } return DirectiveDefinition diff --git a/src/plugin/index.ts b/src/plugin/index.ts index cfafe51a..a8df03b0 100644 --- a/src/plugin/index.ts +++ b/src/plugin/index.ts @@ -12,7 +12,7 @@ interface DialogPluginOptions extends Omit{} const DialogPlugin = { install(app: App, options: DialogPluginOptions) { const DirectivesObj = new DirectiveDialog(app) - app.directive('confirm', DirectivesObj.confirmDefinition) + app.directive('confirm', DirectivesObj.defineConfirm()) const dialog = new PromiseDialog(app, options) diff --git a/src/plugin/promise.dialog.ts b/src/plugin/promise.dialog.ts index 22a8787e..f3bccbef 100644 --- a/src/plugin/promise.dialog.ts +++ b/src/plugin/promise.dialog.ts @@ -15,7 +15,7 @@ interface DialogPluginOptions extends Omit{} export class PromiseDialog { - private dgApp: ComponentInstance; + private dgAppComponentInstance: ComponentInstance; private mounted = false; @@ -35,7 +35,7 @@ export class PromiseDialog { localOptions.promiseResolver = resolve localOptions.promiseRejecter = reject - this.dgApp.commit(mergeObjs(this.globalOptions, localOptions)) + this.dgAppComponentInstance.commit(mergeObjs(this.globalOptions, localOptions)) }) } @@ -63,10 +63,21 @@ export class PromiseDialog { private mountIfNotMounted(): void { if (this.mounted) return - this.dgApp = (() => { + this.dgAppComponentInstance = (() => { + const connectAppContext = true const dialogApp = createApp(DialogComponent) const node = document.createElement('div') document.querySelector('body').appendChild(node) + + if (connectAppContext) { + dialogApp.config.globalProperties = this.app.config.globalProperties + dialogApp._context.components = this.app._context.components + dialogApp._context.directives = this.app._context.directives + dialogApp._context.mixins = this.app._context.mixins + dialogApp._context.provides = this.app._context.provides + } + + return dialogApp.mount(node) as ComponentInstance })() diff --git a/src/views/IndexView.vue b/src/views/IndexView.vue index 1593dafe..88977128 100644 --- a/src/views/IndexView.vue +++ b/src/views/IndexView.vue @@ -11,7 +11,8 @@
- + + Example website