capitalize,
hasOwn,
hasChanged,
- toRawType
+ toRawType,
+ isMap
} from '@vue/shared'
export type CollectionTypes = IterableCollections | WeakCollections
const target = toRaw(this)
const hadItems = target.size !== 0
const oldTarget = __DEV__
- ? target instanceof Map
+ ? isMap(target)
? new Map(target)
: new Set(target)
: undefined
): Iterable & Iterator {
const target = (this as any)[ReactiveFlags.RAW]
const rawTarget = toRaw(target)
- const isMap = rawTarget instanceof Map
- const isPair = method === 'entries' || (method === Symbol.iterator && isMap)
- const isKeyOnly = method === 'keys' && isMap
+ const targetIsMap = isMap(rawTarget)
+ const isPair =
+ method === 'entries' || (method === Symbol.iterator && targetIsMap)
+ const isKeyOnly = method === 'keys' && targetIsMap
const innerIterator = target[method](...args)
const wrap = isReadonly ? toReadonly : isShallow ? toShallow : toReactive
!isReadonly &&
import { TrackOpTypes, TriggerOpTypes } from './operations'
-import { EMPTY_OBJ, isArray, isIntegerKey } from '@vue/shared'
+import { EMPTY_OBJ, isArray, isIntegerKey, isMap } from '@vue/shared'
// The main WeakMap that stores {target -> key -> dep} connections.
// Conceptually, it's easier to think of a dependency as a Dep class
if (key !== void 0) {
add(depsMap.get(key))
}
+
// also run for iteration key on ADD | DELETE | Map.SET
- const shouldTriggerIteration =
- (type === TriggerOpTypes.ADD &&
- (!isArray(target) || isIntegerKey(key))) ||
- (type === TriggerOpTypes.DELETE && !isArray(target))
- if (
- shouldTriggerIteration ||
- (type === TriggerOpTypes.SET && target instanceof Map)
- ) {
- add(depsMap.get(isArray(target) ? 'length' : ITERATE_KEY))
- }
- if (shouldTriggerIteration && target instanceof Map) {
- add(depsMap.get(MAP_KEY_ITERATE_KEY))
+ switch (type) {
+ case TriggerOpTypes.ADD:
+ if (!isArray(target)) {
+ add(depsMap.get(ITERATE_KEY))
+ if (isMap(target)) {
+ add(depsMap.get(MAP_KEY_ITERATE_KEY))
+ }
+ } else if (isIntegerKey(key)) {
+ // new index added to array -> length changes
+ add(depsMap.get('length'))
+ }
+ break
+ case TriggerOpTypes.DELETE:
+ if (!isArray(target)) {
+ add(depsMap.get(ITERATE_KEY))
+ if (isMap(target)) {
+ add(depsMap.get(MAP_KEY_ITERATE_KEY))
+ }
+ }
+ break
+ case TriggerOpTypes.SET:
+ if (isMap(target)) {
+ add(depsMap.get(ITERATE_KEY))
+ }
+ break
}
}
isString,
hasChanged,
NOOP,
- remove
+ remove,
+ isMap,
+ isSet
} from '@vue/shared'
import {
currentInstance,
for (let i = 0; i < value.length; i++) {
traverse(value[i], seen)
}
- } else if (value instanceof Map) {
- value.forEach((v, key) => {
+ } else if (isMap(value)) {
+ value.forEach((_, key) => {
// to register mutation dep for existing keys
traverse(value.get(key), seen)
})
- } else if (value instanceof Set) {
+ } else if (isSet(value)) {
value.forEach(v => {
traverse(v, seen)
})
): key is keyof typeof val => hasOwnProperty.call(val, key)
export const isArray = Array.isArray
-export const isSet = (val: any): boolean => {
- return toRawType(val) === 'Set'
-}
+export const isMap = (val: unknown): val is Map<any, any> =>
+ toTypeString(val) === '[object Map]'
+export const isSet = (val: unknown): val is Set<any> =>
+ toTypeString(val) === '[object Set]'
+
export const isDate = (val: unknown): val is Date => val instanceof Date
export const isFunction = (val: unknown): val is Function =>
typeof val === 'function'
-import { isArray, isObject, isPlainObject } from './index'
+import { isArray, isMap, isObject, isPlainObject, isSet } from './index'
/**
* For converting {{ interpolation }} values to displayed strings.
}
const replacer = (_key: string, val: any) => {
- if (val instanceof Map) {
+ if (isMap(val)) {
return {
[`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val]) => {
;(entries as any)[`${key} =>`] = val
return entries
}, {})
}
- } else if (val instanceof Set) {
+ } else if (isSet(val)) {
return {
[`Set(${val.size})`]: [...val.values()]
}