Skip to content

Commit fee48f8

Browse files
committed
Fix(directive): resolve breaking changes in directive related code
1 parent f3846bf commit fee48f8

File tree

5 files changed

+37
-31
lines changed

5 files changed

+37
-31
lines changed

src/plugin/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// constants
2+
export const DIRECTIVE_ATTRIBUTE_KEY = '__VUEJS_DIALOG__'
23
export const DIALOG_TYPES = {
34
ALERT: 'alert', // ex: Congrats! record created
45
CONFIRM: 'confirm', // ex: Please confirm delete

src/plugin/directive.dialog.ts

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1-
// Directives
2-
31
import { noop, clickNode, cloneObj } from './utilities'
4-
import { CONFIRM_TYPES } from './constants'
2+
import {CONFIRM_TYPES, DIRECTIVE_ATTRIBUTE_KEY} from './constants'
3+
54

65
const DirectiveDialog = function (app) {
76
Object.defineProperties(this, {
8-
Vue: { get: () => app },
9-
confirmDefinition: {
10-
get: this.defineConfirm
11-
}
7+
app: { get: () => app },
128
})
139
}
1410

11+
DirectiveDialog.prototype.shouldIgnoreClick = false
12+
1513
DirectiveDialog.prototype.getConfirmMessage = function (binding) {
1614
if (binding.value && binding.value.message) {
1715
return binding.value.message
@@ -40,15 +38,9 @@ DirectiveDialog.prototype.getThenCallback = function (binding, el) {
4038
// If we got here, it means the default action is to be executed
4139
// We'll then stop the loader if it's enabled and close the dialog
4240
dialog.loading && dialog.close()
43-
44-
// Unbind to allow original event
45-
el.removeEventListener('click', el.VuejsDialog.clickHandler, true)
46-
47-
// Trigger original event
41+
this.shouldIgnoreClick = true
4842
clickNode(el)
49-
50-
// Re-bind listener
51-
el.addEventListener('click', el.VuejsDialog.clickHandler, true)
43+
this.shouldIgnoreClick = false
5244
}
5345
}
5446
}
@@ -61,6 +53,7 @@ DirectiveDialog.prototype.getCatchCallback = function (binding) {
6153
}
6254

6355
DirectiveDialog.prototype.clickHandler = function (event, el, binding) {
56+
if (this.shouldIgnoreClick) return
6457
event.preventDefault()
6558
event.stopImmediatePropagation()
6659

@@ -69,26 +62,26 @@ DirectiveDialog.prototype.clickHandler = function (event, el, binding) {
6962
const thenCallback = this.getThenCallback(binding, el)
7063
const catchCallback = this.getCatchCallback(binding)
7164

72-
this.Vue.dialog
65+
this.app.config.globalProperties.$dialog
7366
.confirm(confirmMessage, options)
7467
.then(thenCallback)
7568
.catch(catchCallback)
7669
}
7770

7871
DirectiveDialog.prototype.defineConfirm = function () {
7972
type BindFn = (el: unknown, binding: unknown) => void
80-
const DirectiveDefinition: {bind: BindFn, unbind: BindFn} = {}
81-
82-
DirectiveDefinition.bind = (el, binding) => {
83-
el.VuejsDialog = el.VuejsDialog || {}
73+
const DirectiveDefinition: {mounted: BindFn, unmounted: BindFn} = {
74+
mounted: (el, binding) => {
75+
el[DIRECTIVE_ATTRIBUTE_KEY] = el[DIRECTIVE_ATTRIBUTE_KEY] || {}
8476

85-
el.VuejsDialog.clickHandler = event => this.clickHandler(event, el, binding)
77+
el[DIRECTIVE_ATTRIBUTE_KEY].clickHandler = event => this.clickHandler(event, el, binding)
8678

87-
el.addEventListener('click', el.VuejsDialog.clickHandler, true)
88-
}
89-
90-
DirectiveDefinition.unbind = (el) => {
91-
el.removeEventListener('click', el.VuejsDialog.clickHandler, true)
79+
el.addEventListener('click', el[DIRECTIVE_ATTRIBUTE_KEY].clickHandler, true)
80+
},
81+
unmounted(el) {
82+
el.removeEventListener('click', el[DIRECTIVE_ATTRIBUTE_KEY].clickHandler, true)
83+
delete el[DIRECTIVE_ATTRIBUTE_KEY]
84+
}
9285
}
9386

9487
return DirectiveDefinition

src/plugin/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ interface DialogPluginOptions extends Omit<DialogWindowOptionsInterface, 'id'>{}
1212
const DialogPlugin = {
1313
install(app: App, options: DialogPluginOptions) {
1414
const DirectivesObj = new DirectiveDialog(app)
15-
app.directive('confirm', DirectivesObj.confirmDefinition)
15+
app.directive('confirm', DirectivesObj.defineConfirm())
1616

1717
const dialog = new PromiseDialog(app, options)
1818

src/plugin/promise.dialog.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ interface DialogPluginOptions extends Omit<DialogWindowOptionsInterface, 'id'>{}
1515

1616

1717
export class PromiseDialog {
18-
private dgApp: ComponentInstance<typeof DialogComponent>;
18+
private dgAppComponentInstance: ComponentInstance<typeof DialogComponent>;
1919

2020
private mounted = false;
2121

@@ -35,7 +35,7 @@ export class PromiseDialog {
3535
localOptions.promiseResolver = resolve
3636
localOptions.promiseRejecter = reject
3737

38-
this.dgApp.commit(mergeObjs(this.globalOptions, localOptions))
38+
this.dgAppComponentInstance.commit(mergeObjs(this.globalOptions, localOptions))
3939
})
4040
}
4141

@@ -63,10 +63,21 @@ export class PromiseDialog {
6363
private mountIfNotMounted(): void {
6464
if (this.mounted) return
6565

66-
this.dgApp = (() => {
66+
this.dgAppComponentInstance = (() => {
67+
const connectAppContext = true
6768
const dialogApp = createApp(DialogComponent)
6869
const node = document.createElement('div')
6970
document.querySelector('body').appendChild(node)
71+
72+
if (connectAppContext) {
73+
dialogApp.config.globalProperties = this.app.config.globalProperties
74+
dialogApp._context.components = this.app._context.components
75+
dialogApp._context.directives = this.app._context.directives
76+
dialogApp._context.mixins = this.app._context.mixins
77+
dialogApp._context.provides = this.app._context.provides
78+
}
79+
80+
7081
return dialogApp.mount(node) as ComponentInstance<DialogComponent>
7182
})()
7283

src/views/IndexView.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
</div>
1212
<hr style="margin: 35px 0;" />
1313
<div style="width: 100%;display: grid; grid-gap: 15px; grid-template-columns: repeat(auto-fill, 200px);justify-content: center">
14-
<button class="dg-btn" v-confirm="'Show some alert!'">Click Alert</button>
14+
<button class="dg-btn" v-confirm="'Please confirm!'">Click Directive</button>
15+
<a href="https://example.com" v-confirm:soft="'Visit external link?'">Example website</a>
1516
</div>
1617
</div>
1718
</template>

0 commit comments

Comments
 (0)