1
+ import { computed , inject , markRaw , nextTick , reactive , useAttrs } from 'vue'
1
2
import { isString , tryOnUnmounted } from '@vueuse/core'
2
- import { computed , getCurrentInstance , inject , markRaw , reactive , useAttrs } from 'vue'
3
3
import type { Component } from 'vue'
4
4
import VueFinalModal from './components/VueFinalModal/VueFinalModal.vue'
5
5
import type CoreModal from './components/CoreModal/CoreModal.vue'
6
- import { internalVfmSymbol , vfmSymbol } from './injectionSymbols'
6
+ import { internalVfmSymbol } from './injectionSymbols'
7
7
8
8
import type { ComponentProps , Constructor , InternalVfm , ModalSlot , ModalSlotOptions , RawProps , UseModalOptions , UseModalOptionsPrivate , UseModalReturnType , Vfm } from './Modal'
9
- import { activeVfm , getActiveVfm , setActiveVfm } from './plugin'
9
+ import { activeVfm , getActiveVfm } from './plugin'
10
10
11
11
/**
12
12
* Returns the vfm instance. Equivalent to using `$vfm` inside
13
13
* templates.
14
14
*/
15
15
export function useVfm ( ) : Vfm {
16
- return getActiveVfm ( ) !
16
+ const vfm = getActiveVfm ( )
17
+ if ( __DEV__ && ! vfm ) {
18
+ throw new Error (
19
+ '[Vue Final Modal]: getActiveVfm was called with no active Vfm. Did you forget to install vfm?\n'
20
+ + '\tconst vfm = createVfm()\n'
21
+ + '\tapp.use(vfm)\n'
22
+ + 'This will fail in production.' ,
23
+ )
24
+ }
25
+
26
+ return vfm !
17
27
}
18
28
19
29
/**
@@ -53,25 +63,8 @@ function withMarkRaw<P>(options: Partial<UseModalOptions<P>>, DefaultComponent:
53
63
* Create a dynamic modal.
54
64
*/
55
65
export function useModal < P = InstanceType < typeof VueFinalModal > [ '$props' ] > ( _options : UseModalOptions < P > ) : UseModalReturnType < P > {
56
- const currentInstance = getCurrentInstance ( )
57
- let vfm = _options . context || ( currentInstance && inject ( vfmSymbol ) )
58
- if ( vfm )
59
- setActiveVfm ( vfm )
60
-
61
- if ( __DEV__ && ! activeVfm ) {
62
- throw new Error (
63
- '[🍍]: getActiveVfm was called with no active Vfm. Did you forget to install vfm?\n'
64
- + '\tconst vfm = createVfm()\n'
65
- + '\tapp.use(vfm)\n'
66
- + 'This will fail in production.' ,
67
- )
68
- }
69
-
70
- vfm = activeVfm
71
-
72
66
const options = reactive ( {
73
67
id : Symbol ( 'useModal' ) ,
74
- context : vfm ,
75
68
modelValue : ! ! _options ?. defaultModelValue ,
76
69
resolveOpened : ( ) => { } ,
77
70
resolveClosed : ( ) => { } ,
@@ -83,16 +76,35 @@ export function useModal<P = InstanceType<typeof VueFinalModal>['$props']>(_opti
83
76
destroy ( )
84
77
} )
85
78
86
- if ( options . modelValue === true )
87
- options . context ?. dynamicModals . push ( options )
79
+ if ( options . modelValue === true ) {
80
+ // nextTick will break the SSR, so use `activeVfm` first and then `useVfm()`
81
+ if ( activeVfm ) {
82
+ activeVfm ?. dynamicModals . push ( options )
83
+ }
84
+ else {
85
+ nextTick ( ( ) => {
86
+ const vfm = useVfm ( )
87
+ vfm ?. dynamicModals . push ( options )
88
+ } )
89
+ }
90
+ }
88
91
89
- function open ( ) : Promise < string > {
92
+ async function open ( ) : Promise < string > {
93
+ // nextTick will break the SSR, so use `activeVfm` first and then `useVfm()`
94
+ let vfm : Vfm
95
+ if ( activeVfm ) {
96
+ vfm = activeVfm
97
+ }
98
+ else {
99
+ await nextTick ( )
100
+ vfm = useVfm ( )
101
+ }
90
102
if ( options . modelValue )
91
103
return Promise . resolve ( '[Vue Final Modal] modal is already opened.' )
92
104
93
105
destroy ( )
94
106
options . modelValue = true
95
- options . context ? .dynamicModals . push ( options )
107
+ vfm . dynamicModals . push ( options )
96
108
97
109
return new Promise ( ( resolve ) => {
98
110
options . resolveOpened = ( ) => resolve ( 'opened' )
@@ -116,8 +128,6 @@ export function useModal<P = InstanceType<typeof VueFinalModal>['$props']>(_opti
116
128
options . defaultModelValue = _options . defaultModelValue
117
129
if ( _options ?. keepAlive !== undefined )
118
130
options . keepAlive = _options ?. keepAlive
119
- if ( _options . context )
120
- options . context = _options . context
121
131
122
132
// patch options.component and options.attrs
123
133
patchComponentOptions ( options , rest )
@@ -156,11 +166,10 @@ export function useModal<P = InstanceType<typeof VueFinalModal>['$props']>(_opti
156
166
}
157
167
158
168
function destroy ( ) : void {
159
- if ( ! options . context )
160
- return
161
- const index = options . context . dynamicModals . indexOf ( options )
169
+ const vfm = useVfm ( )
170
+ const index = vfm . dynamicModals . indexOf ( options )
162
171
if ( index !== - 1 )
163
- options . context . dynamicModals . splice ( index , 1 )
172
+ vfm . dynamicModals . splice ( index , 1 )
164
173
}
165
174
166
175
return {
0 commit comments