fix(v-memo): ensure track block when returning cached vnode (#4270)

fix #4253
This commit is contained in:
edison 2021-08-07 09:44:45 +08:00 committed by GitHub
parent 3b60358d0e
commit a211e271ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 12 additions and 10 deletions

View File

@ -37,7 +37,7 @@ export function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock(\\"div\\", null, [ return (_openBlock(), _createElementBlock(\\"div\\", null, [
(_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.list, ({ x, y }, __, ___, _cached) => { (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.list, ({ x, y }, __, ___, _cached) => {
const _memo = ([x, y === z]) 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\\")) const _item = (_openBlock(), _createElementBlock(\\"span\\", { key: x }, \\"foobar\\"))
_item.memo = _memo _item.memo = _memo
return _item return _item
@ -53,7 +53,7 @@ export function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock(\\"div\\", null, [ return (_openBlock(), _createElementBlock(\\"div\\", null, [
(_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.list, ({ x, y }, __, ___, _cached) => { (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.list, ({ x, y }, __, ___, _cached) => {
const _memo = ([x, y === _ctx.z]) 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 }, [ const _item = (_openBlock(), _createElementBlock(\\"div\\", { key: x }, [
_createElementVNode(\\"span\\", null, \\"foobar\\") _createElementVNode(\\"span\\", null, \\"foobar\\")
])) ]))

View File

@ -209,7 +209,7 @@ export const transformFor = createStructuralDirectiveTransform(
...(keyExp ? [` && _cached.key === `, keyExp] : []), ...(keyExp ? [` && _cached.key === `, keyExp] : []),
` && ${context.helperString( ` && ${context.helperString(
IS_MEMO_SAME IS_MEMO_SAME
)}(_cached.memo, _memo)) return _cached` )}(_cached, _memo)) return _cached`
]), ]),
createCompoundExpression([`const _item = `, childBlock as any]), createCompoundExpression([`const _item = `, childBlock as any]),
createSimpleExpression(`_item.memo = _memo`), createSimpleExpression(`_item.memo = _memo`),

View File

@ -7,11 +7,7 @@ export function withMemo(
index: number index: number
) { ) {
const cached = cache[index] as VNode | undefined const cached = cache[index] as VNode | undefined
if (cached && isMemoSame(cached.memo!, memo)) { if (cached && isMemoSame(cached, memo)) {
// make sure to let parent block track it when returning cached
if (isBlockTreeEnabled > 0 && currentBlock) {
currentBlock.push(cached)
}
return cached return cached
} }
const ret = render() const ret = render()
@ -19,11 +15,17 @@ export function withMemo(
return (cache[index] = ret) 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++) { for (let i = 0; i < prev.length; i++) {
if (prev[i] !== next[i]) { if (prev[i] !== memo[i]) {
return false return false
} }
} }
// make sure to let parent block track it when returning cached
if (isBlockTreeEnabled > 0 && currentBlock) {
currentBlock.push(cached)
}
return true return true
} }