@@ -19,12 +19,14 @@ import {
1919 Component ,
2020 VNode ,
2121 defineComponent ,
22+ nextTick ,
2223 Teleport ,
23- createApp ,
24+ createVNode ,
2425 PropType ,
2526 h ,
2627 onMounted ,
2728 ref ,
29+ render as vueRender ,
2830} from 'vue'
2931import {
3032 isValidElement ,
@@ -50,7 +52,7 @@ type IFormDialogProps = Omit<typeof ElDialogProps, 'title'> & {
5052 okButtonProps ?: typeof ElButtonProps
5153 beforeClose ?: ( cb : Function ) => void
5254 onOpen ?: ( ) => void
53- onOpend ?: ( ) => void
55+ onOpened ?: ( ) => void
5456 onClose ?: ( ) => void
5557 onClosed ?: ( ) => void
5658 onCancel ?: ( ) => void
@@ -120,7 +122,6 @@ export function FormDialog(
120122 root : document . createElement ( 'div' ) ,
121123 form : null ,
122124 promise : null ,
123- app : null ,
124125 instance : null ,
125126 openMiddlewares : [ ] ,
126127 confirmMiddlewares : [ ] ,
@@ -134,8 +135,7 @@ export function FormDialog(
134135 ...props ,
135136 onClosed : ( ) => {
136137 props . onClosed ?.( )
137- env . app ?. unmount ?.( )
138- env . app = null
138+ vueRender ( null , env . root )
139139 env . instance = null
140140 env . root ?. parentNode ?. removeChild ( env . root )
141141 env . root = undefined
@@ -161,135 +161,130 @@ export function FormDialog(
161161 )
162162
163163 const render = ( visible = true , resolve ?: ( ) => any , reject ?: ( ) => any ) => {
164- if ( ! env . instance ) {
165- const ComponentConstructor = observer (
166- defineComponent ( {
167- props : { dialogProps : Object as PropType < typeof ElDialogProps > } ,
168- data ( ) {
169- return {
170- visible : false ,
171- }
172- } ,
173- render ( ) {
174- const {
175- onClose,
176- onClosed,
177- onOpen,
178- onOpend,
179- onOK,
180- onCancel,
181- title,
182- footer,
183- okText,
184- cancelText,
185- okButtonProps,
186- cancelButtonProps,
187- ...dialogProps
188- } = this . dialogProps
189-
190- return h (
191- ElDialog ,
164+ if ( env . instance ) {
165+ env . instance . visible = visible
166+ return
167+ }
168+
169+ const ComponentConstructor = observer (
170+ defineComponent ( {
171+ props : { dialogProps : Object as PropType < typeof ElDialogProps > } ,
172+ data ( ) {
173+ return {
174+ visible : false ,
175+ }
176+ } ,
177+ render ( ) {
178+ const {
179+ onClose,
180+ onClosed,
181+ onOpen,
182+ onOpened,
183+ onOK,
184+ onCancel,
185+ title,
186+ footer,
187+ okText,
188+ cancelText,
189+ okButtonProps,
190+ cancelButtonProps,
191+ ...dialogProps
192+ } = this . dialogProps
193+
194+ const renderFooter = ( ) => {
195+ const FooterPortalTarget = h (
196+ 'span' ,
192197 {
193- class : [ `${ prefixCls } ` ] ,
194- ...dialogProps ,
195- modelValue : this . visible ,
196- 'onUpdate:modelValue' : ( val ) => {
197- this . visible = val
198- } ,
199- onClose : ( ) => {
200- onClose ?.( )
201- } ,
202- onClosed : ( ) => {
203- onClosed ?.( )
204- } ,
205- onOpen : ( ) => {
206- onOpen ?.( )
207- } ,
208- onOpened : ( ) => {
209- onOpend ?.( )
210- } ,
198+ id : PORTAL_TARGET_NAME ,
211199 } ,
212- {
213- default : ( ) =>
214- h ( FormProvider , { form : env . form } , ( ) =>
215- h ( component , { } , { } )
216- ) ,
217- title : ( ) =>
218- h ( 'div' , { } , { default : ( ) => resolveComponent ( title ) } ) ,
219- footer : ( ) =>
220- h (
221- 'div' ,
222- { } ,
223- {
224- default : ( ) => {
225- const FooterPortalTarget = h (
226- 'span' ,
227- {
228- id : PORTAL_TARGET_NAME ,
229- } ,
230- { }
231- )
232- if ( footer === null ) {
233- return [ null , FooterPortalTarget ]
234- } else if ( footer ) {
235- return [ resolveComponent ( footer ) , FooterPortalTarget ]
236- }
237-
238- return [
239- h (
240- ElButton ,
241- {
242- ...cancelButtonProps ,
243- onClick : ( e ) => {
244- onCancel ?.( e )
245- reject ( )
246- } ,
247- } ,
248- {
249- default : ( ) =>
250- resolveComponent (
251- cancelText || '取消'
252- // t('el.popconfirm.cancelButtonText')
253- ) ,
254- }
255- ) ,
256- h (
257- ElButton ,
258- {
259- type : 'primary' ,
260- ...okButtonProps ,
261- loading : env . form . submitting ,
262- onClick : ( e ) => {
263- onOK ?.( e )
264- resolve ( )
265- } ,
266- } ,
267- {
268- default : ( ) =>
269- resolveComponent (
270- okText || '确定'
271- // t('el.popconfirm.confirmButtonText')
272- ) ,
273- }
274- ) ,
275- FooterPortalTarget ,
276- ]
277- } ,
278- }
279- ) ,
280- }
200+ { }
281201 )
282- } ,
283- } )
284- )
285202
286- env . app = createApp ( ComponentConstructor , {
287- dialogProps,
288- parent : getPortalContext ( id as string | symbol ) ,
203+ if ( footer === null ) {
204+ return [ null , FooterPortalTarget ]
205+ }
206+
207+ if ( footer ) {
208+ return [ resolveComponent ( footer ) , FooterPortalTarget ]
209+ }
210+
211+ return [
212+ h (
213+ ElButton ,
214+ {
215+ ...cancelButtonProps ,
216+ onClick : ( ) => {
217+ onCancel ?.( )
218+ reject ( )
219+ } ,
220+ } ,
221+ {
222+ default : ( ) => resolveComponent ( cancelText || '取消' ) ,
223+ }
224+ ) ,
225+ h (
226+ ElButton ,
227+ {
228+ type : 'primary' ,
229+ ...okButtonProps ,
230+ loading : env . form . submitting ,
231+ onClick : ( ) => {
232+ onOK ?.( )
233+ resolve ( )
234+ } ,
235+ } ,
236+ {
237+ default : ( ) => resolveComponent ( okText || '确定' ) ,
238+ }
239+ ) ,
240+ FooterPortalTarget ,
241+ ]
242+ }
243+
244+ return h (
245+ ElDialog ,
246+ {
247+ class : [ `${ prefixCls } ` ] ,
248+ ...dialogProps ,
249+ modelValue : this . visible ,
250+ 'onUpdate:modelValue' : ( val ) => {
251+ this . visible = val
252+ } ,
253+ onClose,
254+ onClosed,
255+ onOpen,
256+ onOpened,
257+ } ,
258+ {
259+ default : ( ) =>
260+ h ( FormProvider , { form : env . form } , ( ) => h ( component , { } , { } ) ) ,
261+ header : ( ) =>
262+ h ( 'div' , { } , { default : ( ) => resolveComponent ( title ) } ) ,
263+ footer : ( ) =>
264+ h (
265+ 'div' ,
266+ { } ,
267+ {
268+ default : renderFooter ,
269+ }
270+ ) ,
271+ }
272+ )
273+ } ,
289274 } )
290- env . instance = env . app . mount ( env . root )
291- }
292- env . instance . visible = visible
275+ )
276+
277+ const vnode = createVNode ( ComponentConstructor , {
278+ dialogProps : dialogProps ,
279+ } )
280+
281+ vnode . appContext = getPortalContext ( id as string | symbol )
282+ vueRender ( vnode , env . root )
283+
284+ nextTick ( ( ) => {
285+ env . instance = vnode . component . proxy
286+ env . instance . visible = visible
287+ } )
293288 }
294289
295290 const formDialog = {
0 commit comments