Skip to content

Commit 99e3705

Browse files
Waleed-KHsxzz
authored andcommitted
refactor(reactivity): encapsulate reactive handlers in class
1 parent 623ba51 commit 99e3705

File tree

1 file changed

+63
-68
lines changed

1 file changed

+63
-68
lines changed

packages/reactivity/src/baseHandlers.ts

Lines changed: 63 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import {
2626
hasChanged,
2727
isArray,
2828
isIntegerKey,
29-
extend,
3029
makeMap
3130
} from '@vue/shared'
3231
import { isRef } from './ref'
@@ -45,11 +44,6 @@ const builtInSymbols = new Set(
4544
.filter(isSymbol)
4645
)
4746

48-
const get = /*#__PURE__*/ createGetter()
49-
const shallowGet = /*#__PURE__*/ createGetter(false, true)
50-
const readonlyGet = /*#__PURE__*/ createGetter(true)
51-
const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true)
52-
5347
const arrayInstrumentations = /*#__PURE__*/ createArrayInstrumentations()
5448

5549
function createArrayInstrumentations() {
@@ -91,22 +85,27 @@ function hasOwnProperty(this: object, key: string) {
9185
return obj.hasOwnProperty(key)
9286
}
9387

94-
function createGetter(isReadonly = false, shallow = false) {
95-
return function get(target: Target, key: string | symbol, receiver: object) {
88+
class BaseReactiveHandler implements ProxyHandler<Target> {
89+
constructor(
90+
protected readonly _isReadonly = false,
91+
protected readonly _shallow = false
92+
) {}
93+
94+
get(target: Target, key: string | symbol, receiver: object) {
9695
if (key === ReactiveFlags.IS_REACTIVE) {
97-
return !isReadonly
96+
return !this._isReadonly
9897
} else if (key === ReactiveFlags.IS_READONLY) {
99-
return isReadonly
98+
return this._isReadonly
10099
} else if (key === ReactiveFlags.IS_SHALLOW) {
101-
return shallow
100+
return this._shallow
102101
} else if (
103102
key === ReactiveFlags.RAW &&
104103
receiver ===
105-
(isReadonly
106-
? shallow
104+
(this._isReadonly
105+
? this._shallow
107106
? shallowReadonlyMap
108107
: readonlyMap
109-
: shallow
108+
: this._shallow
110109
? shallowReactiveMap
111110
: reactiveMap
112111
).get(target)
@@ -116,7 +115,7 @@ function createGetter(isReadonly = false, shallow = false) {
116115

117116
const targetIsArray = isArray(target)
118117

119-
if (!isReadonly) {
118+
if (!this._isReadonly) {
120119
if (targetIsArray && hasOwn(arrayInstrumentations, key)) {
121120
return Reflect.get(arrayInstrumentations, key, receiver)
122121
}
@@ -131,11 +130,11 @@ function createGetter(isReadonly = false, shallow = false) {
131130
return res
132131
}
133132

134-
if (!isReadonly) {
133+
if (!this._isReadonly) {
135134
track(target, TrackOpTypes.GET, key)
136135
}
137136

138-
if (shallow) {
137+
if (this._shallow) {
139138
return res
140139
}
141140

@@ -148,18 +147,19 @@ function createGetter(isReadonly = false, shallow = false) {
148147
// Convert returned value into a proxy as well. we do the isObject check
149148
// here to avoid invalid value warning. Also need to lazy access readonly
150149
// and reactive here to avoid circular dependency.
151-
return isReadonly ? readonly(res) : reactive(res)
150+
return this._isReadonly ? readonly(res) : reactive(res)
152151
}
153152

154153
return res
155154
}
156155
}
157156

158-
const set = /*#__PURE__*/ createSetter()
159-
const shallowSet = /*#__PURE__*/ createSetter(true)
157+
class MutableReactiveHandler extends BaseReactiveHandler {
158+
constructor(shallow = false) {
159+
super(false, shallow)
160+
}
160161

161-
function createSetter(shallow = false) {
162-
return function set(
162+
set(
163163
target: object,
164164
key: string | symbol,
165165
value: unknown,
@@ -169,7 +169,7 @@ function createSetter(shallow = false) {
169169
if (isReadonly(oldValue) && isRef(oldValue) && !isRef(value)) {
170170
return false
171171
}
172-
if (!shallow) {
172+
if (!this._shallow) {
173173
if (!isShallow(value) && !isReadonly(value)) {
174174
oldValue = toRaw(oldValue)
175175
value = toRaw(value)
@@ -197,51 +197,50 @@ function createSetter(shallow = false) {
197197
}
198198
return result
199199
}
200-
}
201200

202-
function deleteProperty(target: object, key: string | symbol): boolean {
203-
const hadKey = hasOwn(target, key)
204-
const oldValue = (target as any)[key]
205-
const result = Reflect.deleteProperty(target, key)
206-
if (result && hadKey) {
207-
trigger(target, TriggerOpTypes.DELETE, key, undefined, oldValue)
201+
deleteProperty(target: object, key: string | symbol): boolean {
202+
const hadKey = hasOwn(target, key)
203+
const oldValue = (target as any)[key]
204+
const result = Reflect.deleteProperty(target, key)
205+
if (result && hadKey) {
206+
trigger(target, TriggerOpTypes.DELETE, key, undefined, oldValue)
207+
}
208+
return result
208209
}
209-
return result
210-
}
211210

212-
function has(target: object, key: string | symbol): boolean {
213-
const result = Reflect.has(target, key)
214-
if (!isSymbol(key) || !builtInSymbols.has(key)) {
215-
track(target, TrackOpTypes.HAS, key)
211+
has(target: object, key: string | symbol): boolean {
212+
const result = Reflect.has(target, key)
213+
if (!isSymbol(key) || !builtInSymbols.has(key)) {
214+
track(target, TrackOpTypes.HAS, key)
215+
}
216+
return result
217+
}
218+
ownKeys(target: object): (string | symbol)[] {
219+
track(
220+
target,
221+
TrackOpTypes.ITERATE,
222+
isArray(target) ? 'length' : ITERATE_KEY
223+
)
224+
return Reflect.ownKeys(target)
216225
}
217-
return result
218-
}
219-
220-
function ownKeys(target: object): (string | symbol)[] {
221-
track(target, TrackOpTypes.ITERATE, isArray(target) ? 'length' : ITERATE_KEY)
222-
return Reflect.ownKeys(target)
223226
}
224227

225-
export const mutableHandlers: ProxyHandler<object> = {
226-
get,
227-
set,
228-
deleteProperty,
229-
has,
230-
ownKeys
231-
}
228+
class ReadonlyReactiveHandler extends BaseReactiveHandler {
229+
constructor(shallow = false) {
230+
super(true, shallow)
231+
}
232232

233-
export const readonlyHandlers: ProxyHandler<object> = {
234-
get: readonlyGet,
235-
set(target, key) {
233+
set(target: object, key: string | symbol) {
236234
if (__DEV__) {
237235
warn(
238236
`Set operation on key "${String(key)}" failed: target is readonly.`,
239237
target
240238
)
241239
}
242240
return true
243-
},
244-
deleteProperty(target, key) {
241+
}
242+
243+
deleteProperty(target: object, key: string | symbol) {
245244
if (__DEV__) {
246245
warn(
247246
`Delete operation on key "${String(key)}" failed: target is readonly.`,
@@ -252,22 +251,18 @@ export const readonlyHandlers: ProxyHandler<object> = {
252251
}
253252
}
254253

255-
export const shallowReactiveHandlers = /*#__PURE__*/ extend(
256-
{},
257-
mutableHandlers,
258-
{
259-
get: shallowGet,
260-
set: shallowSet
261-
}
254+
export const mutableHandlers: ProxyHandler<object> =
255+
/*#__PURE__*/ new MutableReactiveHandler()
256+
257+
export const readonlyHandlers: ProxyHandler<object> =
258+
/*#__PURE__*/ new ReadonlyReactiveHandler()
259+
260+
export const shallowReactiveHandlers = /*#__PURE__*/ new MutableReactiveHandler(
261+
true
262262
)
263263

264264
// Props handlers are special in the sense that it should not unwrap top-level
265265
// refs (in order to allow refs to be explicitly passed down), but should
266266
// retain the reactivity of the normal readonly object.
267-
export const shallowReadonlyHandlers = /*#__PURE__*/ extend(
268-
{},
269-
readonlyHandlers,
270-
{
271-
get: shallowReadonlyGet
272-
}
273-
)
267+
export const shallowReadonlyHandlers =
268+
/*#__PURE__*/ new ReadonlyReactiveHandler(true)

0 commit comments

Comments
 (0)