parent
ba62ccd55d
commit
488e2bcfef
@ -187,5 +187,32 @@ describe('reactivity/reactive', () => {
|
||||
props.n = reactive({ foo: 2 })
|
||||
expect(isReactive(props.n)).toBe(true)
|
||||
})
|
||||
|
||||
test('should not observe when iterating', () => {
|
||||
const shallowSet = shallowReactive(new Set())
|
||||
const a = {}
|
||||
shallowSet.add(a)
|
||||
|
||||
const spreadA = [...shallowSet][0]
|
||||
expect(isReactive(spreadA)).toBe(false)
|
||||
})
|
||||
|
||||
test('should not get reactive entry', () => {
|
||||
const shallowMap = shallowReactive(new Map())
|
||||
const a = {}
|
||||
const key = 'a'
|
||||
|
||||
shallowMap.set(key, a)
|
||||
|
||||
expect(isReactive(shallowMap.get(key))).toBe(false)
|
||||
})
|
||||
|
||||
test('should not get reactive on foreach', () => {
|
||||
const shallowSet = shallowReactive(new Set())
|
||||
const a = {}
|
||||
shallowSet.add(a)
|
||||
|
||||
shallowSet.forEach(x => expect(isReactive(x)).toBe(false))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -22,13 +22,15 @@ const toReactive = <T extends unknown>(value: T): T =>
|
||||
const toReadonly = <T extends unknown>(value: T): T =>
|
||||
isObject(value) ? readonly(value) : value
|
||||
|
||||
const toShallow = <T extends unknown>(value: T): T => value
|
||||
|
||||
const getProto = <T extends CollectionTypes>(v: T): any =>
|
||||
Reflect.getPrototypeOf(v)
|
||||
|
||||
function get(
|
||||
target: MapTypes,
|
||||
key: unknown,
|
||||
wrap: typeof toReactive | typeof toReadonly
|
||||
wrap: typeof toReactive | typeof toReadonly | typeof toShallow
|
||||
) {
|
||||
target = toRaw(target)
|
||||
const rawKey = toRaw(key)
|
||||
@ -132,7 +134,7 @@ function clear(this: IterableCollections) {
|
||||
return result
|
||||
}
|
||||
|
||||
function createForEach(isReadonly: boolean) {
|
||||
function createForEach(isReadonly: boolean, shallow: boolean) {
|
||||
return function forEach(
|
||||
this: IterableCollections,
|
||||
callback: Function,
|
||||
@ -140,7 +142,7 @@ function createForEach(isReadonly: boolean) {
|
||||
) {
|
||||
const observed = this
|
||||
const target = toRaw(observed)
|
||||
const wrap = isReadonly ? toReadonly : toReactive
|
||||
const wrap = isReadonly ? toReadonly : shallow ? toShallow : toReactive
|
||||
!isReadonly && track(target, TrackOpTypes.ITERATE, ITERATE_KEY)
|
||||
// important: create sure the callback is
|
||||
// 1. invoked with the reactive map as `this` and 3rd arg
|
||||
@ -152,14 +154,18 @@ function createForEach(isReadonly: boolean) {
|
||||
}
|
||||
}
|
||||
|
||||
function createIterableMethod(method: string | symbol, isReadonly: boolean) {
|
||||
function createIterableMethod(
|
||||
method: string | symbol,
|
||||
isReadonly: boolean,
|
||||
shallow: boolean
|
||||
) {
|
||||
return function(this: IterableCollections, ...args: unknown[]) {
|
||||
const target = toRaw(this)
|
||||
const isMap = target instanceof Map
|
||||
const isPair = method === 'entries' || (method === Symbol.iterator && isMap)
|
||||
const isKeyOnly = method === 'keys' && isMap
|
||||
const innerIterator = getProto(target)[method].apply(target, args)
|
||||
const wrap = isReadonly ? toReadonly : toReactive
|
||||
const wrap = isReadonly ? toReadonly : shallow ? toShallow : toReactive
|
||||
!isReadonly &&
|
||||
track(
|
||||
target,
|
||||
@ -212,7 +218,22 @@ const mutableInstrumentations: Record<string, Function> = {
|
||||
set,
|
||||
delete: deleteEntry,
|
||||
clear,
|
||||
forEach: createForEach(false)
|
||||
forEach: createForEach(false, false)
|
||||
}
|
||||
|
||||
const shallowInstrumentations: Record<string, Function> = {
|
||||
get(this: MapTypes, key: unknown) {
|
||||
return get(this, key, toShallow)
|
||||
},
|
||||
get size() {
|
||||
return size((this as unknown) as IterableCollections)
|
||||
},
|
||||
has,
|
||||
add,
|
||||
set,
|
||||
delete: deleteEntry,
|
||||
clear,
|
||||
forEach: createForEach(false, true)
|
||||
}
|
||||
|
||||
const readonlyInstrumentations: Record<string, Function> = {
|
||||
@ -227,25 +248,34 @@ const readonlyInstrumentations: Record<string, Function> = {
|
||||
set: createReadonlyMethod(TriggerOpTypes.SET),
|
||||
delete: createReadonlyMethod(TriggerOpTypes.DELETE),
|
||||
clear: createReadonlyMethod(TriggerOpTypes.CLEAR),
|
||||
forEach: createForEach(true)
|
||||
forEach: createForEach(true, false)
|
||||
}
|
||||
|
||||
const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator]
|
||||
iteratorMethods.forEach(method => {
|
||||
mutableInstrumentations[method as string] = createIterableMethod(
|
||||
method,
|
||||
false,
|
||||
false
|
||||
)
|
||||
readonlyInstrumentations[method as string] = createIterableMethod(
|
||||
method,
|
||||
true,
|
||||
false
|
||||
)
|
||||
shallowInstrumentations[method as string] = createIterableMethod(
|
||||
method,
|
||||
true,
|
||||
true
|
||||
)
|
||||
})
|
||||
|
||||
function createInstrumentationGetter(isReadonly: boolean) {
|
||||
const instrumentations = isReadonly
|
||||
? readonlyInstrumentations
|
||||
: mutableInstrumentations
|
||||
function createInstrumentationGetter(isReadonly: boolean, shallow: boolean) {
|
||||
const instrumentations = shallow
|
||||
? shallowInstrumentations
|
||||
: isReadonly
|
||||
? readonlyInstrumentations
|
||||
: mutableInstrumentations
|
||||
|
||||
return (
|
||||
target: CollectionTypes,
|
||||
@ -271,11 +301,15 @@ function createInstrumentationGetter(isReadonly: boolean) {
|
||||
}
|
||||
|
||||
export const mutableCollectionHandlers: ProxyHandler<CollectionTypes> = {
|
||||
get: createInstrumentationGetter(false)
|
||||
get: createInstrumentationGetter(false, false)
|
||||
}
|
||||
|
||||
export const shallowCollectionHandlers: ProxyHandler<CollectionTypes> = {
|
||||
get: createInstrumentationGetter(false, true)
|
||||
}
|
||||
|
||||
export const readonlyCollectionHandlers: ProxyHandler<CollectionTypes> = {
|
||||
get: createInstrumentationGetter(true)
|
||||
get: createInstrumentationGetter(true, false)
|
||||
}
|
||||
|
||||
function checkIdentityKeys(
|
||||
|
@ -7,7 +7,8 @@ import {
|
||||
} from './baseHandlers'
|
||||
import {
|
||||
mutableCollectionHandlers,
|
||||
readonlyCollectionHandlers
|
||||
readonlyCollectionHandlers,
|
||||
shallowCollectionHandlers
|
||||
} from './collectionHandlers'
|
||||
import { UnwrapRef, Ref } from './ref'
|
||||
|
||||
@ -67,7 +68,7 @@ export function shallowReactive<T extends object>(target: T): T {
|
||||
target,
|
||||
false,
|
||||
shallowReactiveHandlers,
|
||||
mutableCollectionHandlers
|
||||
shallowCollectionHandlers
|
||||
)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user