From 9c03a453a06167d611a287e4ad5e12bdf3b5e49e Mon Sep 17 00:00:00 2001 From: Yunfei He Date: Sat, 5 Jun 2021 06:13:41 +0800 Subject: [PATCH] fix(reactivity): should trigger watchEffect when using set to change value of array length (#720) --- src/reactivity/set.ts | 14 ++++++++++---- test/v3/reactivity/set.spec.ts | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 test/v3/reactivity/set.spec.ts diff --git a/src/reactivity/set.ts b/src/reactivity/set.ts index f33032d2..669487cf 100644 --- a/src/reactivity/set.ts +++ b/src/reactivity/set.ts @@ -15,10 +15,16 @@ export function set(target: any, key: any, val: T): T { `Cannot set reactive property on undefined, null, or primitive value: ${target}` ) } - if (isArray(target) && isValidArrayIndex(key)) { - target.length = Math.max(target.length, key) - target.splice(key, 1, val) - return val + if (isArray(target)) { + if (isValidArrayIndex(key)) { + target.length = Math.max(target.length, key) + target.splice(key, 1, val) + return val + } else if (key === 'length' && (val as any) !== target.length) { + target.length = val as any + ;(target as any).__ob__?.dep.notify() + return val + } } if (key in target && !(key in Object.prototype)) { target[key] = val diff --git a/test/v3/reactivity/set.spec.ts b/test/v3/reactivity/set.spec.ts new file mode 100644 index 00000000..24fb1b4f --- /dev/null +++ b/test/v3/reactivity/set.spec.ts @@ -0,0 +1,19 @@ +import { set, ref, watchEffect } from '../../../src' + +describe('reactivity/set', () => { + it('should trigger watchEffect when using set to change value of array length', () => { + const arr = ref([1, 2, 3]) + const spy = jest.fn() + watchEffect( + () => { + spy(arr.value) + }, + { flush: 'sync' } + ) + + expect(spy).toHaveBeenCalledTimes(1) + set(arr.value, 'length', 1) + expect(arr.value.length).toBe(1) + expect(spy).toHaveBeenCalledTimes(2) + }) +})