@@ -11,7 +11,11 @@ const builtInSymbols = new Set(
11
11
. filter ( isSymbol )
12
12
)
13
13
14
- function createGetter ( isReadonly : boolean , shallow = false ) {
14
+ const get = createGetter ( )
15
+ const readonlyGet = createGetter ( true )
16
+ const shallowReadonlyGet = createGetter ( true , true )
17
+
18
+ function createGetter ( isReadonly = false , shallow = false ) {
15
19
return function get ( target : object , key : string | symbol , receiver : object ) {
16
20
const res = Reflect . get ( target , key , receiver )
17
21
if ( isSymbol ( key ) && builtInSymbols . has ( key ) ) {
@@ -36,39 +40,60 @@ function createGetter(isReadonly: boolean, shallow = false) {
36
40
}
37
41
}
38
42
39
- function set (
40
- target : object ,
41
- key : string | symbol ,
42
- value : unknown ,
43
- receiver : object
44
- ) : boolean {
45
- value = toRaw ( value )
46
- const oldValue = ( target as any ) [ key ]
47
- if ( isRef ( oldValue ) && ! isRef ( value ) ) {
48
- oldValue . value = value
49
- return true
50
- }
51
- const hadKey = hasOwn ( target , key )
52
- const result = Reflect . set ( target , key , value , receiver )
53
- // don't trigger if target is something up in the prototype chain of original
54
- if ( target === toRaw ( receiver ) ) {
55
- /* istanbul ignore else */
56
- if ( __DEV__ ) {
57
- const extraInfo = { oldValue, newValue : value }
58
- if ( ! hadKey ) {
59
- trigger ( target , TriggerOpTypes . ADD , key , extraInfo )
60
- } else if ( hasChanged ( value , oldValue ) ) {
61
- trigger ( target , TriggerOpTypes . SET , key , extraInfo )
43
+ const set = createSetter ( )
44
+ const readonlySet = createSetter ( true )
45
+ const shallowReadonlySet = createSetter ( true , true )
46
+
47
+ function createSetter ( isReadonly = false , shallow = false ) {
48
+ return function set (
49
+ target : object ,
50
+ key : string | symbol ,
51
+ value : unknown ,
52
+ receiver : object
53
+ ) : boolean {
54
+ if ( isReadonly && LOCKED ) {
55
+ if ( __DEV__ ) {
56
+ console . warn (
57
+ `Set operation on key "${ String ( key ) } " failed: target is readonly.` ,
58
+ target
59
+ )
60
+ }
61
+ return true
62
+ }
63
+
64
+ const oldValue = ( target as any ) [ key ]
65
+ if ( ! shallow ) {
66
+ value = toRaw ( value )
67
+ if ( isRef ( oldValue ) && ! isRef ( value ) ) {
68
+ oldValue . value = value
69
+ return true
62
70
}
63
71
} else {
64
- if ( ! hadKey ) {
65
- trigger ( target , TriggerOpTypes . ADD , key )
66
- } else if ( hasChanged ( value , oldValue ) ) {
67
- trigger ( target , TriggerOpTypes . SET , key )
72
+ // in shallow mode, objects are set as-is regardless of reactive or not
73
+ }
74
+
75
+ const hadKey = hasOwn ( target , key )
76
+ const result = Reflect . set ( target , key , value , receiver )
77
+ // don't trigger if target is something up in the prototype chain of original
78
+ if ( target === toRaw ( receiver ) ) {
79
+ /* istanbul ignore else */
80
+ if ( __DEV__ ) {
81
+ const extraInfo = { oldValue, newValue : value }
82
+ if ( ! hadKey ) {
83
+ trigger ( target , TriggerOpTypes . ADD , key , extraInfo )
84
+ } else if ( hasChanged ( value , oldValue ) ) {
85
+ trigger ( target , TriggerOpTypes . SET , key , extraInfo )
86
+ }
87
+ } else {
88
+ if ( ! hadKey ) {
89
+ trigger ( target , TriggerOpTypes . ADD , key )
90
+ } else if ( hasChanged ( value , oldValue ) ) {
91
+ trigger ( target , TriggerOpTypes . SET , key )
92
+ }
68
93
}
69
94
}
95
+ return result
70
96
}
71
- return result
72
97
}
73
98
74
99
function deleteProperty ( target : object , key : string | symbol ) : boolean {
@@ -98,35 +123,18 @@ function ownKeys(target: object): (string | number | symbol)[] {
98
123
}
99
124
100
125
export const mutableHandlers : ProxyHandler < object > = {
101
- get : createGetter ( false ) ,
126
+ get,
102
127
set,
103
128
deleteProperty,
104
129
has,
105
130
ownKeys
106
131
}
107
132
108
133
export const readonlyHandlers : ProxyHandler < object > = {
109
- get : createGetter ( true ) ,
110
-
111
- set (
112
- target : object ,
113
- key : string | symbol ,
114
- value : unknown ,
115
- receiver : object
116
- ) : boolean {
117
- if ( LOCKED ) {
118
- if ( __DEV__ ) {
119
- console . warn (
120
- `Set operation on key "${ String ( key ) } " failed: target is readonly.` ,
121
- target
122
- )
123
- }
124
- return true
125
- } else {
126
- return set ( target , key , value , receiver )
127
- }
128
- } ,
129
-
134
+ get : readonlyGet ,
135
+ set : readonlySet ,
136
+ has,
137
+ ownKeys,
130
138
deleteProperty ( target : object , key : string | symbol ) : boolean {
131
139
if ( LOCKED ) {
132
140
if ( __DEV__ ) {
@@ -141,16 +149,14 @@ export const readonlyHandlers: ProxyHandler<object> = {
141
149
} else {
142
150
return deleteProperty ( target , key )
143
151
}
144
- } ,
145
-
146
- has,
147
- ownKeys
152
+ }
148
153
}
149
154
150
155
// props handlers are special in the sense that it should not unwrap top-level
151
156
// refs (in order to allow refs to be explicitly passed down), but should
152
157
// retain the reactivity of the normal readonly object.
153
158
export const shallowReadonlyHandlers : ProxyHandler < object > = {
154
159
...readonlyHandlers ,
155
- get : createGetter ( true , true )
160
+ get : shallowReadonlyGet ,
161
+ set : shallowReadonlySet
156
162
}
0 commit comments