From 6779bff537d3506e3bb3b30eadfbe66def7bd3cb Mon Sep 17 00:00:00 2001 From: lidlanca <8693091+lidlanca@users.noreply.github.com> Date: Mon, 9 Aug 2021 15:39:22 -0400 Subject: [PATCH] feat(runtime-core): support dynamic / external array in v-memo (#4255) --- .../__tests__/helpers/withMemo.spec.ts | 41 +++++++++++++++++++ packages/runtime-core/src/helpers/withMemo.ts | 7 +++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/packages/runtime-core/__tests__/helpers/withMemo.spec.ts b/packages/runtime-core/__tests__/helpers/withMemo.spec.ts index 93aac0d8f..5d6590bd9 100644 --- a/packages/runtime-core/__tests__/helpers/withMemo.spec.ts +++ b/packages/runtime-core/__tests__/helpers/withMemo.spec.ts @@ -10,6 +10,47 @@ describe('v-memo', () => { return [el, vm] } + test('on with external array', async () => { + const [el, vm] = mount({ + template: `
{{ arr[0] }} {{ arr[1] }} {{arr[2] ?? '_' }} ({{c}})
{{c}}`, + data: () => ({ arr: [0, 0], c: 0 }) + }) + expect(el.innerHTML).toBe(`
0 0 _ (0)
0`) + + let [x, y, z] = [0, 1, 2] + + // change at index x - should update + vm.arr[x]++ + vm.c++ + await nextTick() + expect(el.innerHTML).toBe(`
1 0 _ (1)
1`) + + // change at index y - should update + vm.arr[y]++ + vm.c++ + await nextTick() + expect(el.innerHTML).toBe(`
1 1 _ (2)
2`) + + // noop change - should NOT update + vm.arr[x] = vm.arr[0] + vm.arr[y] = vm.arr[1] + vm.c++ + await nextTick() + expect(el.innerHTML).toBe(`
1 1 _ (2)
3`) + + // add item 3rd item - should update + vm.arr[z] = 0 + vm.c++ + await nextTick() + expect(el.innerHTML).toBe(`
1 1 0 (4)
4`) + + // remove 3rd item - should update + vm.arr = vm.arr.slice(0, vm.arr.length - 1) + vm.c++ + await nextTick() + expect(el.innerHTML).toBe(`
1 1 _ (5)
5`) + }) + test('on normal element', async () => { const [el, vm] = mount({ template: `
{{ x }} {{ y }}
`, diff --git a/packages/runtime-core/src/helpers/withMemo.ts b/packages/runtime-core/src/helpers/withMemo.ts index 43b1fc282..3e40365ea 100644 --- a/packages/runtime-core/src/helpers/withMemo.ts +++ b/packages/runtime-core/src/helpers/withMemo.ts @@ -11,12 +11,17 @@ export function withMemo( return cached } const ret = render() - ret.memo = memo + + // shallow clone + ret.memo = memo.slice() return (cache[index] = ret) } export function isMemoSame(cached: VNode, memo: any[]) { const prev: any[] = cached.memo! + if (prev.length != memo.length) { + return false + } for (let i = 0; i < prev.length; i++) { if (prev[i] !== memo[i]) { return false