1
- import { isObject , toRawType } from '@vue/shared'
1
+ import { isObject , toRawType , def } from '@vue/shared'
2
2
import {
3
3
mutableHandlers ,
4
4
readonlyHandlers ,
@@ -13,25 +13,38 @@ import { UnwrapRef, Ref } from './ref'
13
13
import { makeMap } from '@vue/shared'
14
14
15
15
// WeakMaps that store {raw <-> observed} pairs.
16
- const rawToReactive = new WeakMap < any , any > ( )
17
- const reactiveToRaw = new WeakMap < any , any > ( )
18
- const rawToReadonly = new WeakMap < any , any > ( )
19
- const readonlyToRaw = new WeakMap < any , any > ( )
16
+ // const rawToReactive = new WeakMap<any, any>()
17
+ // const reactiveToRaw = new WeakMap<any, any>()
18
+ // const rawToReadonly = new WeakMap<any, any>()
19
+ // const readonlyToRaw = new WeakMap<any, any>()
20
20
21
- // WeakSets for values that are marked readonly or non-reactive during
22
- // observable creation.
23
- const rawValues = new WeakSet < any > ( )
21
+ export const enum ReactiveFlags {
22
+ skip = '__v_skip' ,
23
+ isReactive = '__v_isReactive' ,
24
+ isReadonly = '__v_isReadonly' ,
25
+ raw = '__v_raw' ,
26
+ reactive = '__v_reactive' ,
27
+ readonly = '__v_readonly'
28
+ }
29
+
30
+ interface Target {
31
+ __v_skip ?: boolean
32
+ __v_isReactive ?: boolean
33
+ __v_isReadonly ?: boolean
34
+ __v_raw ?: any
35
+ __v_reactive ?: any
36
+ __v_readonly ?: any
37
+ }
24
38
25
39
const collectionTypes = new Set < Function > ( [ Set , Map , WeakMap , WeakSet ] )
26
40
const isObservableType = /*#__PURE__*/ makeMap (
27
41
'Object,Array,Map,Set,WeakMap,WeakSet'
28
42
)
29
43
30
- const canObserve = ( value : any ) : boolean => {
44
+ const canObserve = ( value : Target ) : boolean => {
31
45
return (
32
- ! value . _isVNode &&
46
+ ! value . __v_skip &&
33
47
isObservableType ( toRawType ( value ) ) &&
34
- ! rawValues . has ( value ) &&
35
48
! Object . isFrozen ( value )
36
49
)
37
50
}
@@ -42,13 +55,12 @@ type UnwrapNestedRefs<T> = T extends Ref ? T : UnwrapRef<T>
42
55
export function reactive < T extends object > ( target : T ) : UnwrapNestedRefs < T >
43
56
export function reactive ( target : object ) {
44
57
// if trying to observe a readonly proxy, return the readonly version.
45
- if ( readonlyToRaw . has ( target ) ) {
58
+ if ( target && ( target as Target ) . __v_isReadonly ) {
46
59
return target
47
60
}
48
61
return createReactiveObject (
49
62
target ,
50
- rawToReactive ,
51
- reactiveToRaw ,
63
+ false ,
52
64
mutableHandlers ,
53
65
mutableCollectionHandlers
54
66
)
@@ -60,8 +72,7 @@ export function reactive(target: object) {
60
72
export function shallowReactive < T extends object > ( target : T ) : T {
61
73
return createReactiveObject (
62
74
target ,
63
- rawToReactive ,
64
- reactiveToRaw ,
75
+ false ,
65
76
shallowReactiveHandlers ,
66
77
mutableCollectionHandlers
67
78
)
@@ -72,8 +83,7 @@ export function readonly<T extends object>(
72
83
) : Readonly < UnwrapNestedRefs < T > > {
73
84
return createReactiveObject (
74
85
target ,
75
- rawToReadonly ,
76
- readonlyToRaw ,
86
+ true ,
77
87
readonlyHandlers ,
78
88
readonlyCollectionHandlers
79
89
)
@@ -88,17 +98,15 @@ export function shallowReadonly<T extends object>(
88
98
) : Readonly < { [ K in keyof T ] : UnwrapNestedRefs < T [ K ] > } > {
89
99
return createReactiveObject (
90
100
target ,
91
- rawToReadonly ,
92
- readonlyToRaw ,
101
+ true ,
93
102
shallowReadonlyHandlers ,
94
103
readonlyCollectionHandlers
95
104
)
96
105
}
97
106
98
107
function createReactiveObject (
99
- target : unknown ,
100
- toProxy : WeakMap < any , any > ,
101
- toRaw : WeakMap < any , any > ,
108
+ target : Target ,
109
+ isReadonly : boolean ,
102
110
baseHandlers : ProxyHandler < any > ,
103
111
collectionHandlers : ProxyHandler < any >
104
112
) {
@@ -108,15 +116,16 @@ function createReactiveObject(
108
116
}
109
117
return target
110
118
}
119
+ // target is already a Proxy, return it.
120
+ // excpetion: calling readonly() on a reactive object
121
+ if ( target . __v_raw && ! ( isReadonly && target . __v_isReactive ) ) {
122
+ return target
123
+ }
111
124
// target already has corresponding Proxy
112
- let observed = toProxy . get ( target )
125
+ let observed = isReadonly ? target . __v_readonly : target . __v_reactive
113
126
if ( observed !== void 0 ) {
114
127
return observed
115
128
}
116
- // target is already a Proxy
117
- if ( toRaw . has ( target ) ) {
118
- return target
119
- }
120
129
// only a whitelist of value types can be observed.
121
130
if ( ! canObserve ( target ) ) {
122
131
return target
@@ -125,30 +134,34 @@ function createReactiveObject(
125
134
? collectionHandlers
126
135
: baseHandlers
127
136
observed = new Proxy ( target , handlers )
128
- toProxy . set ( target , observed )
129
- toRaw . set ( observed , target )
137
+ def (
138
+ target ,
139
+ isReadonly ? ReactiveFlags . readonly : ReactiveFlags . reactive ,
140
+ observed
141
+ )
130
142
return observed
131
143
}
132
144
133
145
export function isReactive ( value : unknown ) : boolean {
134
- value = readonlyToRaw . get ( value ) || value
135
- return reactiveToRaw . has ( value )
146
+ if ( isReadonly ( value ) ) {
147
+ return isReactive ( ( value as Target ) . __v_raw )
148
+ }
149
+ return ! ! ( value && ( value as Target ) . __v_isReactive )
136
150
}
137
151
138
152
export function isReadonly ( value : unknown ) : boolean {
139
- return readonlyToRaw . has ( value )
153
+ return ! ! ( value && ( value as Target ) . __v_isReadonly )
140
154
}
141
155
142
156
export function isProxy ( value : unknown ) : boolean {
143
- return readonlyToRaw . has ( value ) || reactiveToRaw . has ( value )
157
+ return isReactive ( value ) || isReadonly ( value )
144
158
}
145
159
146
160
export function toRaw < T > ( observed : T ) : T {
147
- observed = readonlyToRaw . get ( observed ) || observed
148
- return reactiveToRaw . get ( observed ) || observed
161
+ return ( observed && toRaw ( ( observed as Target ) . __v_raw ) ) || observed
149
162
}
150
163
151
164
export function markRaw < T extends object > ( value : T ) : T {
152
- rawValues . add ( value )
165
+ def ( value , ReactiveFlags . skip , true )
153
166
return value
154
167
}
0 commit comments