|
|
@@ -1,4 +1,4 @@
|
|
|
-import { isObject, toRawType, def, hasOwn, makeMap } from '@vue/shared'
|
|
|
+import { isObject, toRawType, def, hasOwn } from '@vue/shared'
|
|
|
import {
|
|
|
mutableHandlers,
|
|
|
readonlyHandlers,
|
|
|
@@ -30,17 +30,31 @@ export interface Target {
|
|
|
[ReactiveFlags.READONLY]?: any
|
|
|
}
|
|
|
|
|
|
-const collectionTypes = new Set<Function>([Set, Map, WeakMap, WeakSet])
|
|
|
-const isObservableType = /*#__PURE__*/ makeMap(
|
|
|
- 'Object,Array,Map,Set,WeakMap,WeakSet'
|
|
|
-)
|
|
|
+const enum TargetType {
|
|
|
+ INVALID = 0,
|
|
|
+ COMMON = 1,
|
|
|
+ COLLECTION = 2
|
|
|
+}
|
|
|
|
|
|
-const canObserve = (value: Target): boolean => {
|
|
|
- return (
|
|
|
- !value[ReactiveFlags.SKIP] &&
|
|
|
- isObservableType(toRawType(value)) &&
|
|
|
- Object.isExtensible(value)
|
|
|
- )
|
|
|
+function targetTypeMap(rawType: string) {
|
|
|
+ switch (rawType) {
|
|
|
+ case 'Object':
|
|
|
+ case 'Array':
|
|
|
+ return TargetType.COMMON
|
|
|
+ case 'Map':
|
|
|
+ case 'Set':
|
|
|
+ case 'WeakMap':
|
|
|
+ case 'WeakSet':
|
|
|
+ return TargetType.COLLECTION
|
|
|
+ default:
|
|
|
+ return TargetType.INVALID
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function getTargetType(value: Target) {
|
|
|
+ return value[ReactiveFlags.SKIP] || !Object.isExtensible(value)
|
|
|
+ ? TargetType.INVALID
|
|
|
+ : targetTypeMap(toRawType(value))
|
|
|
}
|
|
|
|
|
|
// only unwrap nested ref
|
|
|
@@ -148,12 +162,13 @@ function createReactiveObject(
|
|
|
return target[reactiveFlag]
|
|
|
}
|
|
|
// only a whitelist of value types can be observed.
|
|
|
- if (!canObserve(target)) {
|
|
|
+ const targetType = getTargetType(target)
|
|
|
+ if (targetType === TargetType.INVALID) {
|
|
|
return target
|
|
|
}
|
|
|
const observed = new Proxy(
|
|
|
target,
|
|
|
- collectionTypes.has(target.constructor) ? collectionHandlers : baseHandlers
|
|
|
+ targetType === TargetType.COLLECTION ? collectionHandlers : baseHandlers
|
|
|
)
|
|
|
def(target, reactiveFlag, observed)
|
|
|
return observed
|