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)) { | ||||
|     type = TargetType.COMMON | ||||
|   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