@@ -176,11 +176,13 @@ export function defineCustomElement(
176176 if ( isPlainObject ( Comp ) ) extend ( Comp , extraOptions )
177177 class VueCustomElement extends VueElement {
178178 static def = Comp
179+ static asyncDef : any | null = null
179180 constructor ( initialProps ?: Record < string , any > ) {
180- super ( Comp , initialProps , _createApp )
181+ super ( VueCustomElement . def , initialProps , _createApp )
181182 }
182183 }
183184
185+ _defineProps ( VueCustomElement . prototype , Comp )
184186 return VueCustomElement
185187}
186188
@@ -406,7 +408,16 @@ export class VueElement
406408 if ( asyncDef ) {
407409 this . _pendingResolve = asyncDef ( ) . then ( ( def : InnerComponentDef ) => {
408410 def . configureApp = this . _def . configureApp
409- resolve ( ( this . _def = def ) , true )
411+ this . _def = def
412+ const ctor = this . constructor as any
413+ if ( ! ctor . asyncDef ) {
414+ const proto = Object . getPrototypeOf ( this )
415+ _defineProps ( proto , def )
416+ ctor . asyncDef = def
417+ } else if ( ctor . asyncDef !== def ) {
418+ warn ( 'async loader returned inconsistent value' )
419+ }
420+ resolve ( def , true )
410421 } )
411422 } else {
412423 resolve ( this . _def )
@@ -431,7 +442,7 @@ export class VueElement
431442 const exposed = this . _instance && this . _instance . exposed
432443 if ( ! exposed ) return
433444 for ( const key in exposed ) {
434- if ( ! hasOwn ( this , key ) ) {
445+ if ( ! hasOwn ( this , key ) && ! hasOwn ( Object . getPrototypeOf ( this ) , key ) ) {
435446 // exposed properties are readonly
436447 Object . defineProperty ( this , key , {
437448 // unwrap ref to be consistent with public instance behavior
@@ -451,20 +462,9 @@ export class VueElement
451462 for ( const key of Object . keys ( this ) ) {
452463 if ( key [ 0 ] !== '_' && declaredPropKeys . includes ( key ) ) {
453464 this . _setProp ( key , this [ key as keyof this] )
465+ delete this [ key as keyof this]
454466 }
455467 }
456-
457- // defining getter/setters on prototype
458- for ( const key of declaredPropKeys . map ( camelize ) ) {
459- Object . defineProperty ( this , key , {
460- get ( ) {
461- return this . _getProp ( key )
462- } ,
463- set ( val ) {
464- this . _setProp ( key , val , true , true )
465- } ,
466- } )
467- }
468468 }
469469
470470 protected _setAttr ( key : string ) : void {
@@ -688,6 +688,28 @@ export class VueElement
688688 }
689689}
690690
691+ function _defineProps ( proto : object , def : InnerComponentDef ) {
692+ const { props } = def
693+ const declaredPropKeys = isArray ( props ) ? props : Object . keys ( props || { } )
694+ // defining getter/setters on prototype
695+ for ( const key of declaredPropKeys . map ( camelize ) ) {
696+ Object . defineProperty ( proto , key , {
697+ get ( ) {
698+ return this . _getProp ( key )
699+ } ,
700+ set ( val ) {
701+ if ( this . _resolved ) {
702+ this . _setProp ( key , val , true , true )
703+ } else {
704+ // when pre-upgrade or connect, set values directly on the instance
705+ Reflect . set ( { } , key , val , this )
706+ }
707+ } ,
708+ enumerable : true ,
709+ } )
710+ }
711+ }
712+
691713export function useHost ( caller ?: string ) : VueElement | null {
692714 const instance = getCurrentInstance ( )
693715 const el = instance && ( instance . ce as VueElement )
0 commit comments