fix(reactivity): readonly+reactive collection should also expose readonly+reactive values
fix #1772
This commit is contained in:
parent
48576e582c
commit
ed4381020f
@ -205,6 +205,22 @@ describe('reactivity/readonly', () => {
|
||||
).toHaveBeenWarned()
|
||||
})
|
||||
|
||||
// #1772
|
||||
test('readonly + reactive should make get() value also readonly + reactive', () => {
|
||||
const map = reactive(new Collection())
|
||||
const roMap = readonly(map)
|
||||
const key = {}
|
||||
map.set(key, {})
|
||||
|
||||
const item = map.get(key)
|
||||
expect(isReactive(item)).toBe(true)
|
||||
expect(isReadonly(item)).toBe(false)
|
||||
|
||||
const roItem = roMap.get(key)
|
||||
expect(isReactive(roItem)).toBe(true)
|
||||
expect(isReadonly(roItem)).toBe(true)
|
||||
})
|
||||
|
||||
if (Collection === Map) {
|
||||
test('should retrieve readonly values on iteration', () => {
|
||||
const key1 = {}
|
||||
@ -223,6 +239,28 @@ describe('reactivity/readonly', () => {
|
||||
expect(isReadonly(value)).toBe(true)
|
||||
}
|
||||
})
|
||||
|
||||
test('should retrieve reactive + readonly values on iteration', () => {
|
||||
const key1 = {}
|
||||
const key2 = {}
|
||||
const original = reactive(new Collection([[key1, {}], [key2, {}]]))
|
||||
const wrapped: any = readonly(original)
|
||||
expect(wrapped.size).toBe(2)
|
||||
for (const [key, value] of wrapped) {
|
||||
expect(isReadonly(key)).toBe(true)
|
||||
expect(isReadonly(value)).toBe(true)
|
||||
expect(isReactive(key)).toBe(true)
|
||||
expect(isReactive(value)).toBe(true)
|
||||
}
|
||||
wrapped.forEach((value: any) => {
|
||||
expect(isReadonly(value)).toBe(true)
|
||||
expect(isReactive(value)).toBe(true)
|
||||
})
|
||||
for (const value of wrapped.values()) {
|
||||
expect(isReadonly(value)).toBe(true)
|
||||
expect(isReactive(value)).toBe(true)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
@ -32,17 +32,20 @@ function get(
|
||||
key: unknown,
|
||||
wrap: typeof toReactive | typeof toReadonly | typeof toShallow
|
||||
) {
|
||||
target = toRaw(target)
|
||||
// #1772: readonly(reactive(Map)) should return readonly + reactive version
|
||||
// of the value
|
||||
target = (target as any)[ReactiveFlags.RAW]
|
||||
const rawTarget = toRaw(target)
|
||||
const rawKey = toRaw(key)
|
||||
if (key !== rawKey) {
|
||||
track(target, TrackOpTypes.GET, key)
|
||||
track(rawTarget, TrackOpTypes.GET, key)
|
||||
}
|
||||
track(target, TrackOpTypes.GET, rawKey)
|
||||
const { has, get } = getProto(target)
|
||||
if (has.call(target, key)) {
|
||||
return wrap(get.call(target, key))
|
||||
} else if (has.call(target, rawKey)) {
|
||||
return wrap(get.call(target, rawKey))
|
||||
track(rawTarget, TrackOpTypes.GET, rawKey)
|
||||
const { has } = getProto(rawTarget)
|
||||
if (has.call(rawTarget, key)) {
|
||||
return wrap(target.get(key))
|
||||
} else if (has.call(rawTarget, rawKey)) {
|
||||
return wrap(target.get(rawKey))
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,15 +179,16 @@ function createIterableMethod(
|
||||
this: IterableCollections,
|
||||
...args: unknown[]
|
||||
): Iterable & Iterator {
|
||||
const target = toRaw(this)
|
||||
const isMap = target instanceof Map
|
||||
const target = (this as any)[ReactiveFlags.RAW]
|
||||
const rawTarget = toRaw(this)
|
||||
const isMap = rawTarget instanceof Map
|
||||
const isPair = method === 'entries' || (method === Symbol.iterator && isMap)
|
||||
const isKeyOnly = method === 'keys' && isMap
|
||||
const innerIterator = getProto(target)[method].apply(target, args)
|
||||
const innerIterator = target[method](...args)
|
||||
const wrap = isReadonly ? toReadonly : shallow ? toShallow : toReactive
|
||||
!isReadonly &&
|
||||
track(
|
||||
target,
|
||||
rawTarget,
|
||||
TrackOpTypes.ITERATE,
|
||||
isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user