From a211e271ee8c328e68afc0fe5ab86fabd7e4a320 Mon Sep 17 00:00:00 2001 From: edison Date: Sat, 7 Aug 2021 09:44:45 +0800 Subject: [PATCH] fix(v-memo): ensure track block when returning cached vnode (#4270) fix #4253 --- .../transforms/__snapshots__/vMemo.spec.ts.snap | 4 ++-- packages/compiler-core/src/transforms/vFor.ts | 2 +- packages/runtime-core/src/helpers/withMemo.ts | 16 +++++++++------- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/vMemo.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/vMemo.spec.ts.snap index 7e654286290..349eb97a468 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/vMemo.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/vMemo.spec.ts.snap @@ -37,7 +37,7 @@ export function render(_ctx, _cache) { return (_openBlock(), _createElementBlock(\\"div\\", null, [ (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.list, ({ x, y }, __, ___, _cached) => { const _memo = ([x, y === z]) - if (_cached && _cached.key === x && _isMemoSame(_cached.memo, _memo)) return _cached + if (_cached && _cached.key === x && _isMemoSame(_cached, _memo)) return _cached const _item = (_openBlock(), _createElementBlock(\\"span\\", { key: x }, \\"foobar\\")) _item.memo = _memo return _item @@ -53,7 +53,7 @@ export function render(_ctx, _cache) { return (_openBlock(), _createElementBlock(\\"div\\", null, [ (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.list, ({ x, y }, __, ___, _cached) => { const _memo = ([x, y === _ctx.z]) - if (_cached && _cached.key === x && _isMemoSame(_cached.memo, _memo)) return _cached + if (_cached && _cached.key === x && _isMemoSame(_cached, _memo)) return _cached const _item = (_openBlock(), _createElementBlock(\\"div\\", { key: x }, [ _createElementVNode(\\"span\\", null, \\"foobar\\") ])) diff --git a/packages/compiler-core/src/transforms/vFor.ts b/packages/compiler-core/src/transforms/vFor.ts index 5d3049f0c95..c6d444ed8dc 100644 --- a/packages/compiler-core/src/transforms/vFor.ts +++ b/packages/compiler-core/src/transforms/vFor.ts @@ -209,7 +209,7 @@ export const transformFor = createStructuralDirectiveTransform( ...(keyExp ? [` && _cached.key === `, keyExp] : []), ` && ${context.helperString( IS_MEMO_SAME - )}(_cached.memo, _memo)) return _cached` + )}(_cached, _memo)) return _cached` ]), createCompoundExpression([`const _item = `, childBlock as any]), createSimpleExpression(`_item.memo = _memo`), diff --git a/packages/runtime-core/src/helpers/withMemo.ts b/packages/runtime-core/src/helpers/withMemo.ts index e3ac03bb0be..43b1fc282bc 100644 --- a/packages/runtime-core/src/helpers/withMemo.ts +++ b/packages/runtime-core/src/helpers/withMemo.ts @@ -7,11 +7,7 @@ export function withMemo( index: number ) { const cached = cache[index] as VNode | undefined - if (cached && isMemoSame(cached.memo!, memo)) { - // make sure to let parent block track it when returning cached - if (isBlockTreeEnabled > 0 && currentBlock) { - currentBlock.push(cached) - } + if (cached && isMemoSame(cached, memo)) { return cached } const ret = render() @@ -19,11 +15,17 @@ export function withMemo( return (cache[index] = ret) } -export function isMemoSame(prev: any[], next: any[]) { +export function isMemoSame(cached: VNode, memo: any[]) { + const prev: any[] = cached.memo! for (let i = 0; i < prev.length; i++) { - if (prev[i] !== next[i]) { + if (prev[i] !== memo[i]) { return false } } + + // make sure to let parent block track it when returning cached + if (isBlockTreeEnabled > 0 && currentBlock) { + currentBlock.push(cached) + } return true }