From: daiwei Date: Mon, 4 Aug 2025 14:12:06 +0000 (+0800) Subject: fix: treat v-if/v-else/v-else-if as a single node X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a83231043ff7dcbbf109cdfb0d82bd0e105b3a5a;p=thirdparty%2Fvuejs%2Fcore.git fix: treat v-if/v-else/v-else-if as a single node --- diff --git a/packages/compiler-vapor/src/generators/operation.ts b/packages/compiler-vapor/src/generators/operation.ts index 83fcc9a283..2069c9f6a6 100644 --- a/packages/compiler-vapor/src/generators/operation.ts +++ b/packages/compiler-vapor/src/generators/operation.ts @@ -169,7 +169,7 @@ function genInsertionState( context: CodegenContext, ): CodeFragment[] { const { seenChildIndexes } = context - let { parent, childIndex, anchor } = operation + const { parent, childIndex, anchor } = operation const insertionAnchor = anchor == null ? undefined @@ -178,11 +178,14 @@ function genInsertionState( : `n${anchor}` // the index of next block node, used to locate node during hydration + // only passed when anchor is null and childIndex > 0 let index: number | undefined - if (anchor == null) { + if (anchor == null && childIndex) { const existingOffset = seenChildIndexes.get(parent!) - index = existingOffset ? existingOffset + 1 : childIndex - if (index) seenChildIndexes.set(parent!, index) + seenChildIndexes.set( + parent!, + (index = existingOffset ? existingOffset + 1 : childIndex), + ) } return [ diff --git a/packages/compiler-vapor/src/generators/template.ts b/packages/compiler-vapor/src/generators/template.ts index 3071014332..d7d29d5d15 100644 --- a/packages/compiler-vapor/src/generators/template.ts +++ b/packages/compiler-vapor/src/generators/template.ts @@ -53,9 +53,11 @@ export function genChildren( const { children } = dynamic let offset = 0 + let ifBranchCount = 0 let prev: [variable: string, elementIndex: number] | undefined for (const [index, child] of children.entries()) { + if (child.isIfBranch) ifBranchCount++ if (child.flags & DynamicFlag.NON_TEMPLATE) { offset-- } @@ -97,7 +99,11 @@ export function genChildren( // this ensures that insertionAnchor points to the current node itself // rather than its next sibling, since insertionAnchor is used as the // hydration node - `${asAnchor ? index - 1 : index}` + `${ + (asAnchor ? index - 1 : index) - + // treat v-if/v-else/v-else-if as a single node + ifBranchCount + }` if (elementIndex === 0) { pushBlock(...genCall(helper('child'), from, childIndex)) diff --git a/packages/compiler-vapor/src/ir/index.ts b/packages/compiler-vapor/src/ir/index.ts index 90d063b8b0..96110207d5 100644 --- a/packages/compiler-vapor/src/ir/index.ts +++ b/packages/compiler-vapor/src/ir/index.ts @@ -272,6 +272,7 @@ export interface IRDynamicInfo { hasDynamicChild?: boolean operation?: OperationNode needsKey?: boolean + isIfBranch?: boolean } export interface IREffect { diff --git a/packages/compiler-vapor/src/transforms/transformChildren.ts b/packages/compiler-vapor/src/transforms/transformChildren.ts index 5480187ebd..71e3171890 100644 --- a/packages/compiler-vapor/src/transforms/transformChildren.ts +++ b/packages/compiler-vapor/src/transforms/transformChildren.ts @@ -92,7 +92,7 @@ function processDynamicChildren(context: TransformContext) { prevDynamics, context, -1 /* prepend */, - children.findIndex(c => c === prevDynamics[0]), + getChildIndex(children, prevDynamics[0]), ) } prevDynamics = [] @@ -106,7 +106,7 @@ function processDynamicChildren(context: TransformContext) { prevDynamics, context, undefined, - children.findIndex(c => c === prevDynamics[0]), + getChildIndex(children, prevDynamics[0]), ) } } @@ -134,3 +134,17 @@ function registerInsertion( } } } + +function getChildIndex( + children: IRDynamicInfo[], + child: IRDynamicInfo, +): number { + let index = 0 + for (const c of children) { + // treat v-if/v-else/v-else-if as a single node + if (c.isIfBranch) continue + if (c === child) break + index++ + } + return index +} diff --git a/packages/compiler-vapor/src/transforms/vIf.ts b/packages/compiler-vapor/src/transforms/vIf.ts index 2426fa0215..cc135863ec 100644 --- a/packages/compiler-vapor/src/transforms/vIf.ts +++ b/packages/compiler-vapor/src/transforms/vIf.ts @@ -57,6 +57,7 @@ export function processIf( } } } else { + context.dynamic.isIfBranch = true // check the adjacent v-if const siblingIf = getSiblingIf(context, true)