diff --git a/packages/reactivity/__tests__/reactive.spec.ts b/packages/reactivity/__tests__/reactive.spec.ts index 6d2c6896..46ce75b6 100644 --- a/packages/reactivity/__tests__/reactive.spec.ts +++ b/packages/reactivity/__tests__/reactive.spec.ts @@ -1,11 +1,5 @@ import { ref, isRef } from '../src/ref' -import { - reactive, - isReactive, - toRaw, - markRaw, - shallowReactive -} from '../src/reactive' +import { reactive, isReactive, toRaw, markRaw } from '../src/reactive' import { mockWarn } from '@vue/shared' import { computed } from '../src/computed' @@ -175,44 +169,4 @@ describe('reactivity/reactive', () => { }) expect(isReactive(obj.foo)).toBe(false) }) - - describe('shallowReactive', () => { - test('should not make non-reactive properties reactive', () => { - const props = shallowReactive({ n: { foo: 1 } }) - expect(isReactive(props.n)).toBe(false) - }) - - test('should keep reactive properties reactive', () => { - const props: any = shallowReactive({ n: reactive({ foo: 1 }) }) - props.n = reactive({ foo: 2 }) - expect(isReactive(props.n)).toBe(true) - }) - - test('should not observe when iterating', () => { - const shallowSet = shallowReactive(new Set()) - const a = {} - shallowSet.add(a) - - const spreadA = [...shallowSet][0] - expect(isReactive(spreadA)).toBe(false) - }) - - test('should not get reactive entry', () => { - const shallowMap = shallowReactive(new Map()) - const a = {} - const key = 'a' - - shallowMap.set(key, a) - - expect(isReactive(shallowMap.get(key))).toBe(false) - }) - - test('should not get reactive on foreach', () => { - const shallowSet = shallowReactive(new Set()) - const a = {} - shallowSet.add(a) - - shallowSet.forEach(x => expect(isReactive(x)).toBe(false)) - }) - }) }) diff --git a/packages/reactivity/__tests__/shallowReactive.spec.ts b/packages/reactivity/__tests__/shallowReactive.spec.ts new file mode 100644 index 00000000..5997d045 --- /dev/null +++ b/packages/reactivity/__tests__/shallowReactive.spec.ts @@ -0,0 +1,125 @@ +import { shallowReactive, isReactive, reactive } from '../src/reactive' +import { effect } from '../src/effect' + +describe('shallowReactive', () => { + test('should not make non-reactive properties reactive', () => { + const props = shallowReactive({ n: { foo: 1 } }) + expect(isReactive(props.n)).toBe(false) + }) + + test('should keep reactive properties reactive', () => { + const props: any = shallowReactive({ n: reactive({ foo: 1 }) }) + props.n = reactive({ foo: 2 }) + expect(isReactive(props.n)).toBe(true) + }) + + describe('collections', () => { + test('should be reactive', () => { + const shallowSet = shallowReactive(new Set()) + const a = {} + let size + + effect(() => { + size = shallowSet.size + }) + + expect(size).toBe(0) + + shallowSet.add(a) + expect(size).toBe(1) + + shallowSet.delete(a) + expect(size).toBe(0) + }) + + test('should not observe when iterating', () => { + const shallowSet = shallowReactive(new Set()) + const a = {} + shallowSet.add(a) + + const spreadA = [...shallowSet][0] + expect(isReactive(spreadA)).toBe(false) + }) + + test('should not get reactive entry', () => { + const shallowMap = shallowReactive(new Map()) + const a = {} + const key = 'a' + + shallowMap.set(key, a) + + expect(isReactive(shallowMap.get(key))).toBe(false) + }) + + test('should not get reactive on foreach', () => { + const shallowSet = shallowReactive(new Set()) + const a = {} + shallowSet.add(a) + + shallowSet.forEach(x => expect(isReactive(x)).toBe(false)) + }) + + // #1210 + test('onTrack on called on objectSpread', () => { + const onTrackFn = jest.fn() + const shallowSet = shallowReactive(new Set()) + let a + effect( + () => { + a = Array.from(shallowSet) + }, + { + onTrack: onTrackFn + } + ) + + expect(a).toMatchObject([]) + expect(onTrackFn).toHaveBeenCalled() + }) + }) + + describe('array', () => { + test('should be reactive', () => { + const shallowArray = shallowReactive([]) + const a = {} + let size + + effect(() => { + size = shallowArray.length + }) + + expect(size).toBe(0) + + shallowArray.push(a) + expect(size).toBe(1) + + shallowArray.pop() + expect(size).toBe(0) + }) + test('should not observe when iterating', () => { + const shallowArray = shallowReactive([]) + const a = {} + shallowArray.push(a) + + const spreadA = [...shallowArray][0] + expect(isReactive(spreadA)).toBe(false) + }) + + test('onTrack on called on objectSpread', () => { + const onTrackFn = jest.fn() + const shallowArray = shallowReactive([]) + let a + effect( + () => { + a = Array.from(shallowArray) + }, + { + onTrack: onTrackFn + } + ) + + expect(a).toMatchObject([]) + expect(onTrackFn).toHaveBeenCalled() + }) + }) +}) diff --git a/packages/reactivity/src/collectionHandlers.ts b/packages/reactivity/src/collectionHandlers.ts index 181a6e21..b9b45c78 100644 --- a/packages/reactivity/src/collectionHandlers.ts +++ b/packages/reactivity/src/collectionHandlers.ts @@ -265,7 +265,7 @@ iteratorMethods.forEach(method => { ) shallowInstrumentations[method as string] = createIterableMethod( method, - true, + false, true ) })