@@ -349,6 +349,10 @@ export interface ComponentInternalInstance {
349
349
slots : InternalSlots
350
350
refs : Data
351
351
emit : EmitFn
352
+
353
+ attrsProxy : Data | null
354
+ slotsProxy : Slots | null
355
+
352
356
/**
353
357
* used for keeping track of .once event handlers on components
354
358
* @internal
@@ -536,6 +540,9 @@ export function createComponentInstance(
536
540
setupState : EMPTY_OBJ ,
537
541
setupContext : null ,
538
542
543
+ attrsProxy : null ,
544
+ slotsProxy : null ,
545
+
539
546
// suspense related
540
547
suspense,
541
548
suspenseId : suspense ? suspense . pendingId : 0 ,
@@ -923,31 +930,57 @@ export function finishComponentSetup(
923
930
}
924
931
}
925
932
926
- function createAttrsProxy ( instance : ComponentInternalInstance ) : Data {
927
- return new Proxy (
928
- instance . attrs ,
929
- __DEV__
930
- ? {
931
- get ( target , key : string ) {
932
- markAttrsAccessed ( )
933
- track ( instance , TrackOpTypes . GET , '$attrs' )
934
- return target [ key ]
935
- } ,
936
- set ( ) {
937
- warn ( `setupContext.attrs is readonly.` )
938
- return false
939
- } ,
940
- deleteProperty ( ) {
941
- warn ( `setupContext.attrs is readonly.` )
942
- return false
933
+ function getAttrsProxy ( instance : ComponentInternalInstance ) : Data {
934
+ return (
935
+ instance . attrsProxy ||
936
+ ( instance . attrsProxy = new Proxy (
937
+ instance . attrs ,
938
+ __DEV__
939
+ ? {
940
+ get ( target , key : string ) {
941
+ markAttrsAccessed ( )
942
+ track ( instance , TrackOpTypes . GET , '$attrs' )
943
+ return target [ key ]
944
+ } ,
945
+ set ( ) {
946
+ warn ( `setupContext.attrs is readonly.` )
947
+ return false
948
+ } ,
949
+ deleteProperty ( ) {
950
+ warn ( `setupContext.attrs is readonly.` )
951
+ return false
952
+ }
943
953
}
944
- }
945
- : {
946
- get ( target , key : string ) {
947
- track ( instance , TrackOpTypes . GET , '$attrs' )
948
- return target [ key ]
954
+ : {
955
+ get ( target , key : string ) {
956
+ track ( instance , TrackOpTypes . GET , '$attrs' )
957
+ return target [ key ]
958
+ }
949
959
}
950
- }
960
+ ) )
961
+ )
962
+ }
963
+
964
+ /**
965
+ * Dev-only
966
+ */
967
+ function getSlotsProxy ( instance : ComponentInternalInstance ) : Slots {
968
+ return (
969
+ instance . slotsProxy ||
970
+ ( instance . slotsProxy = new Proxy ( instance . slots , {
971
+ get ( target , key : string ) {
972
+ track ( instance , TrackOpTypes . GET , '$slots' )
973
+ return target [ key ]
974
+ } ,
975
+ set ( ) {
976
+ warn ( `setupContext.slots is readonly.` )
977
+ return false
978
+ } ,
979
+ deleteProperty ( ) {
980
+ warn ( `setupContext.slots is readonly.` )
981
+ return false
982
+ }
983
+ } ) )
951
984
)
952
985
}
953
986
@@ -978,16 +1011,15 @@ export function createSetupContext(
978
1011
instance . exposed = exposed || { }
979
1012
}
980
1013
981
- let attrs : Data
982
1014
if ( __DEV__ ) {
983
1015
// We use getters in dev in case libs like test-utils overwrite instance
984
1016
// properties (overwrites should not be done in prod)
985
1017
return Object . freeze ( {
986
1018
get attrs ( ) {
987
- return attrs || ( attrs = createAttrsProxy ( instance ) )
1019
+ return getAttrsProxy ( instance )
988
1020
} ,
989
1021
get slots ( ) {
990
- return shallowReadonly ( instance . slots )
1022
+ return getSlotsProxy ( instance )
991
1023
} ,
992
1024
get emit ( ) {
993
1025
return ( event : string , ...args : any [ ] ) => instance . emit ( event , ...args )
@@ -997,7 +1029,7 @@ export function createSetupContext(
997
1029
} else {
998
1030
return {
999
1031
get attrs ( ) {
1000
- return attrs || ( attrs = createAttrsProxy ( instance ) )
1032
+ return getAttrsProxy ( instance )
1001
1033
} ,
1002
1034
slots : instance . slots ,
1003
1035
emit : instance . emit ,
0 commit comments