@@ -176,11 +176,13 @@ export function defineCustomElement(
176
176
if ( isPlainObject ( Comp ) ) extend ( Comp , extraOptions )
177
177
class VueCustomElement extends VueElement {
178
178
static def = Comp
179
+ static asyncDef : any | null = null
179
180
constructor ( initialProps ?: Record < string , any > ) {
180
- super ( Comp , initialProps , _createApp )
181
+ super ( VueCustomElement . def , initialProps , _createApp )
181
182
}
182
183
}
183
184
185
+ _defineProps ( VueCustomElement . prototype , Comp )
184
186
return VueCustomElement
185
187
}
186
188
@@ -406,7 +408,16 @@ export class VueElement
406
408
if ( asyncDef ) {
407
409
this . _pendingResolve = asyncDef ( ) . then ( ( def : InnerComponentDef ) => {
408
410
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 )
410
421
} )
411
422
} else {
412
423
resolve ( this . _def )
@@ -431,7 +442,7 @@ export class VueElement
431
442
const exposed = this . _instance && this . _instance . exposed
432
443
if ( ! exposed ) return
433
444
for ( const key in exposed ) {
434
- if ( ! hasOwn ( this , key ) ) {
445
+ if ( ! hasOwn ( this , key ) && ! hasOwn ( Object . getPrototypeOf ( this ) , key ) ) {
435
446
// exposed properties are readonly
436
447
Object . defineProperty ( this , key , {
437
448
// unwrap ref to be consistent with public instance behavior
@@ -451,20 +462,9 @@ export class VueElement
451
462
for ( const key of Object . keys ( this ) ) {
452
463
if ( key [ 0 ] !== '_' && declaredPropKeys . includes ( key ) ) {
453
464
this . _setProp ( key , this [ key as keyof this] )
465
+ delete this [ key as keyof this]
454
466
}
455
467
}
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
- }
468
468
}
469
469
470
470
protected _setAttr ( key : string ) : void {
@@ -688,6 +688,28 @@ export class VueElement
688
688
}
689
689
}
690
690
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
+
691
713
export function useHost ( caller ?: string ) : VueElement | null {
692
714
const instance = getCurrentInstance ( )
693
715
const el = instance && ( instance . ce as VueElement )
0 commit comments