1+ import { computed , inject , markRaw , nextTick , reactive , useAttrs } from 'vue'
12import { isString , tryOnUnmounted } from '@vueuse/core'
2- import { computed , getCurrentInstance , inject , markRaw , reactive , useAttrs } from 'vue'
33import type { Component } from 'vue'
44import VueFinalModal from './components/VueFinalModal/VueFinalModal.vue'
55import type CoreModal from './components/CoreModal/CoreModal.vue'
6- import { internalVfmSymbol , vfmSymbol } from './injectionSymbols'
6+ import { internalVfmSymbol } from './injectionSymbols'
77
88import 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'
1010
1111/**
1212 * Returns the vfm instance. Equivalent to using `$vfm` inside
1313 * templates.
1414 */
1515export 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 !
1727}
1828
1929/**
@@ -53,25 +63,8 @@ function withMarkRaw<P>(options: Partial<UseModalOptions<P>>, DefaultComponent:
5363 * Create a dynamic modal.
5464 */
5565export 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-
7266 const options = reactive ( {
7367 id : Symbol ( 'useModal' ) ,
74- context : vfm ,
7568 modelValue : ! ! _options ?. defaultModelValue ,
7669 resolveOpened : ( ) => { } ,
7770 resolveClosed : ( ) => { } ,
@@ -83,16 +76,35 @@ export function useModal<P = InstanceType<typeof VueFinalModal>['$props']>(_opti
8376 destroy ( )
8477 } )
8578
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+ }
8891
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+ }
90102 if ( options . modelValue )
91103 return Promise . resolve ( '[Vue Final Modal] modal is already opened.' )
92104
93105 destroy ( )
94106 options . modelValue = true
95- options . context ? .dynamicModals . push ( options )
107+ vfm . dynamicModals . push ( options )
96108
97109 return new Promise ( ( resolve ) => {
98110 options . resolveOpened = ( ) => resolve ( 'opened' )
@@ -116,8 +128,6 @@ export function useModal<P = InstanceType<typeof VueFinalModal>['$props']>(_opti
116128 options . defaultModelValue = _options . defaultModelValue
117129 if ( _options ?. keepAlive !== undefined )
118130 options . keepAlive = _options ?. keepAlive
119- if ( _options . context )
120- options . context = _options . context
121131
122132 // patch options.component and options.attrs
123133 patchComponentOptions ( options , rest )
@@ -156,11 +166,10 @@ export function useModal<P = InstanceType<typeof VueFinalModal>['$props']>(_opti
156166 }
157167
158168 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 )
162171 if ( index !== - 1 )
163- options . context . dynamicModals . splice ( index , 1 )
172+ vfm . dynamicModals . splice ( index , 1 )
164173 }
165174
166175 return {
0 commit comments