From 379da16608a484a72824c25d2283c3845c8d96f1 Mon Sep 17 00:00:00 2001 From: HcySunYang Date: Mon, 21 Sep 2020 15:16:50 +0800 Subject: [PATCH 1/2] fix(compiler-core): make v-once work with v-if/else-if/else --- .../__tests__/transforms/vOnce.spec.ts | 19 ++++++++--- packages/compiler-core/src/ast.ts | 2 +- packages/compiler-core/src/transforms/vIf.ts | 34 ++++++++++++++----- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/packages/compiler-core/__tests__/transforms/vOnce.spec.ts b/packages/compiler-core/__tests__/transforms/vOnce.spec.ts index 3983aa9605a..a18a0947d00 100644 --- a/packages/compiler-core/__tests__/transforms/vOnce.spec.ts +++ b/packages/compiler-core/__tests__/transforms/vOnce.spec.ts @@ -99,15 +99,26 @@ describe('compiler: v-once transform', () => { expect(generate(root).code).toMatchSnapshot() }) - test('with v-if', () => { - const root = transformWithOnce(`
`) + test('with v-if/else', () => { + const root = transformWithOnce(`

`) expect(root.cached).toBe(1) expect(root.helpers).toContain(SET_BLOCK_TRACKING) expect(root.children[0]).toMatchObject({ type: NodeTypes.IF, - // should cache the entire v-if expression, not just a single branch + // should cache the entire v-if/else-if/else expression, not just a single branch codegenNode: { - type: NodeTypes.JS_CACHE_EXPRESSION + type: NodeTypes.JS_CACHE_EXPRESSION, + value: { + type: NodeTypes.JS_CONDITIONAL_EXPRESSION, + consequent: { + type: NodeTypes.VNODE_CALL, + tag: `"div"` + }, + alternate: { + type: NodeTypes.VNODE_CALL, + tag: `"p"` + } + } } }) }) diff --git a/packages/compiler-core/src/ast.ts b/packages/compiler-core/src/ast.ts index 42c93402616..35849833c66 100644 --- a/packages/compiler-core/src/ast.ts +++ b/packages/compiler-core/src/ast.ts @@ -236,7 +236,7 @@ export interface CompoundExpressionNode extends Node { export interface IfNode extends Node { type: NodeTypes.IF branches: IfBranchNode[] - codegenNode?: IfConditionalExpression + codegenNode?: IfConditionalExpression | CacheExpression //

} export interface IfBranchNode extends Node { diff --git a/packages/compiler-core/src/transforms/vIf.ts b/packages/compiler-core/src/transforms/vIf.ts index 2c00349254d..05a67594f93 100644 --- a/packages/compiler-core/src/transforms/vIf.ts +++ b/packages/compiler-core/src/transforms/vIf.ts @@ -20,7 +20,8 @@ import { IfNode, createVNodeCall, AttributeNode, - locStub + locStub, + CacheExpression } from '../ast' import { createCompilerError, ErrorCodes } from '../errors' import { processExpression } from './transformExpression' @@ -62,13 +63,7 @@ export const transformIf = createStructuralDirectiveTransform( ) as IfConditionalExpression } else { // attach this branch's codegen node to the v-if root. - let parentCondition = ifNode.codegenNode! - while ( - parentCondition.alternate.type === - NodeTypes.JS_CONDITIONAL_EXPRESSION - ) { - parentCondition = parentCondition.alternate - } + const parentCondition = getConditionExpression(ifNode.codegenNode!) parentCondition.alternate = createCodegenNodeForBranch( branch, key + ifNode.branches.length - 1, @@ -293,3 +288,26 @@ function isSameKey( } return true } + +function getConditionExpression( + node: IfConditionalExpression | CacheExpression +): IfConditionalExpression { + const alternateNode = + node.type === NodeTypes.JS_CONDITIONAL_EXPRESSION + ? node.alternate.type === NodeTypes.JS_CONDITIONAL_EXPRESSION + ? (node.alternate as IfConditionalExpression) + : undefined + : node.type === NodeTypes.JS_CACHE_EXPRESSION + ? node.value.type === NodeTypes.JS_CONDITIONAL_EXPRESSION + ? node.value.alternate.type === NodeTypes.JS_CONDITIONAL_EXPRESSION + ? (node.value.alternate as IfConditionalExpression) + : undefined + : undefined + : undefined + + return alternateNode + ? getConditionExpression(alternateNode) + : node.type === NodeTypes.JS_CONDITIONAL_EXPRESSION + ? node + : (node.value as IfConditionalExpression) +} From a5ba85357d32d0f3cc2b9288ffa97d517f516520 Mon Sep 17 00:00:00 2001 From: Evan You Date: Mon, 5 Oct 2020 11:53:21 -0400 Subject: [PATCH 2/2] Update vIf.ts --- packages/compiler-core/src/transforms/vIf.ts | 33 ++++++++------------ 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/packages/compiler-core/src/transforms/vIf.ts b/packages/compiler-core/src/transforms/vIf.ts index 05a67594f93..00832a9acec 100644 --- a/packages/compiler-core/src/transforms/vIf.ts +++ b/packages/compiler-core/src/transforms/vIf.ts @@ -63,7 +63,7 @@ export const transformIf = createStructuralDirectiveTransform( ) as IfConditionalExpression } else { // attach this branch's codegen node to the v-if root. - const parentCondition = getConditionExpression(ifNode.codegenNode!) + const parentCondition = getParentCondition(ifNode.codegenNode!) parentCondition.alternate = createCodegenNodeForBranch( branch, key + ifNode.branches.length - 1, @@ -289,25 +289,18 @@ function isSameKey( return true } -function getConditionExpression( +function getParentCondition( node: IfConditionalExpression | CacheExpression ): IfConditionalExpression { - const alternateNode = - node.type === NodeTypes.JS_CONDITIONAL_EXPRESSION - ? node.alternate.type === NodeTypes.JS_CONDITIONAL_EXPRESSION - ? (node.alternate as IfConditionalExpression) - : undefined - : node.type === NodeTypes.JS_CACHE_EXPRESSION - ? node.value.type === NodeTypes.JS_CONDITIONAL_EXPRESSION - ? node.value.alternate.type === NodeTypes.JS_CONDITIONAL_EXPRESSION - ? (node.value.alternate as IfConditionalExpression) - : undefined - : undefined - : undefined - - return alternateNode - ? getConditionExpression(alternateNode) - : node.type === NodeTypes.JS_CONDITIONAL_EXPRESSION - ? node - : (node.value as IfConditionalExpression) + while (true) { + if (node.type === NodeTypes.JS_CONDITIONAL_EXPRESSION) { + if (node.alternate.type === NodeTypes.JS_CONDITIONAL_EXPRESSION) { + node = node.alternate + } else { + return node + } + } else if (node.type === NodeTypes.JS_CACHE_EXPRESSION) { + node = node.value as IfConditionalExpression + } + } }