mirror of https://github.com/vuejs/core.git
fix(reactivity): support custom Symbol.toStringTag for collections
This commit is contained in:
parent
d9444e5523
commit
b42d264da0
|
@ -130,6 +130,35 @@ describe('reactivity/reactive', () => {
|
|||
expect(dummy).toBe(2)
|
||||
})
|
||||
|
||||
test('custom collection type with custom Symbol.toStringTag is handled as a collection', () => {
|
||||
class MyCustomMap extends Map {
|
||||
get [Symbol.toStringTag]() {
|
||||
return 'MyCustomMap'
|
||||
}
|
||||
}
|
||||
|
||||
const myCustomMap = new MyCustomMap()
|
||||
|
||||
expect(Object.prototype.toString.call(myCustomMap)).toBe(
|
||||
'[object MyCustomMap]',
|
||||
)
|
||||
|
||||
const observed = reactive(myCustomMap)
|
||||
|
||||
expect(isReactive(observed)).toBe(true)
|
||||
expect(isProxy(observed)).toBe(true)
|
||||
|
||||
let dummy: boolean = false
|
||||
effect(() => {
|
||||
dummy = observed.has('foo')
|
||||
})
|
||||
|
||||
expect(dummy).toBe(false)
|
||||
|
||||
observed.set('foo', 'bar')
|
||||
expect(dummy).toBe(true)
|
||||
})
|
||||
|
||||
test('observed value should proxy mutations to original (Object)', () => {
|
||||
const original: any = { foo: 1 }
|
||||
const observed = reactive(original)
|
||||
|
|
|
@ -68,14 +68,26 @@ function getTargetType(value: Target) {
|
|||
if (value[ReactiveFlags.SKIP] || !Object.isExtensible(value)) {
|
||||
return TargetType.INVALID
|
||||
}
|
||||
const type = targetTypeMap(toRawType(value))
|
||||
let type = targetTypeMap(rawType)
|
||||
|
||||
// If we got INVALID but the value is actually a plain object (even if its raw type was changed
|
||||
// by a custom Symbol.toStringTag), then force it to be reactive.
|
||||
if (type === TargetType.INVALID && isPlainObject(value)) {
|
||||
let type = targetTypeMap(toRawType(value))
|
||||
|
||||
// If the raw type mapping fails, we add extra checks:
|
||||
if (type === TargetType.INVALID) {
|
||||
// Check for collection types even if they have a custom Symbol.toStringTag.
|
||||
if (
|
||||
value instanceof Map ||
|
||||
value instanceof Set ||
|
||||
value instanceof WeakMap ||
|
||||
value instanceof WeakSet
|
||||
) {
|
||||
type = TargetType.COLLECTION
|
||||
}
|
||||
// Check if the value is a plain object despite a custom tag.
|
||||
else if (isPlainObject(value)) {
|
||||
type = TargetType.COMMON
|
||||
}
|
||||
}
|
||||
|
||||
return type
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue