Skip to content

fix(runtime-vapor): reset insertion state to avoid duplicate block inserts during non-hydration #13220

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: vapor
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/compiler-vapor/src/generators/operation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export function genOperationWithInsertionState(
): CodeFragment[] {
const [frag, push] = buildCodeFragment()
if (isBlockOperation(oper) && oper.parent) {
push(...genInsertionstate(oper, context))
push(...genInsertionState(oper, context))
}
push(...genOperation(oper, context))
return frag
Expand Down Expand Up @@ -152,7 +152,7 @@ export function genEffect(
return frag
}

function genInsertionstate(
function genInsertionState(
operation: InsertionStateTypes,
context: CodegenContext,
): CodeFragment[] {
Expand Down
8 changes: 7 additions & 1 deletion packages/runtime-vapor/src/apiCreateFor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ import type { DynamicSlot } from './componentSlots'
import { renderEffect } from './renderEffect'
import { VaporVForFlags } from '../../shared/src/vaporFlags'
import { isHydrating, locateHydrationNode } from './dom/hydration'
import { insertionAnchor, insertionParent } from './insertionState'
import {
insertionAnchor,
insertionParent,
resetInsertionState,
} from './insertionState'

class ForBlock extends VaporFragment {
scope: EffectScope | undefined
Expand Down Expand Up @@ -72,6 +76,8 @@ export const createFor = (
const _insertionAnchor = insertionAnchor
if (isHydrating) {
locateHydrationNode()
} else {
resetInsertionState()
}

let isMounted = false
Expand Down
8 changes: 7 additions & 1 deletion packages/runtime-vapor/src/apiCreateIf.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { type Block, type BlockFn, DynamicFragment, insert } from './block'
import { isHydrating, locateHydrationNode } from './dom/hydration'
import { insertionAnchor, insertionParent } from './insertionState'
import {
insertionAnchor,
insertionParent,
resetInsertionState,
} from './insertionState'
import { renderEffect } from './renderEffect'

export function createIf(
Expand All @@ -13,6 +17,8 @@ export function createIf(
const _insertionAnchor = insertionAnchor
if (isHydrating) {
locateHydrationNode()
} else {
resetInsertionState()
}

let frag: Block
Expand Down
8 changes: 7 additions & 1 deletion packages/runtime-vapor/src/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ import {
} from './componentSlots'
import { hmrReload, hmrRerender } from './hmr'
import { isHydrating, locateHydrationNode } from './dom/hydration'
import { insertionAnchor, insertionParent } from './insertionState'
import {
insertionAnchor,
insertionParent,
resetInsertionState,
} from './insertionState'

export { currentInstance } from '@vue/runtime-dom'

Expand Down Expand Up @@ -142,6 +146,8 @@ export function createComponent(
const _insertionAnchor = insertionAnchor
if (isHydrating) {
locateHydrationNode()
} else {
resetInsertionState()
}

// vdom interop enabled and component is not an explicit vapor component
Expand Down
8 changes: 7 additions & 1 deletion packages/runtime-vapor/src/componentSlots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import { rawPropsProxyHandlers } from './componentProps'
import { currentInstance, isRef } from '@vue/runtime-dom'
import type { LooseRawProps, VaporComponentInstance } from './component'
import { renderEffect } from './renderEffect'
import { insertionAnchor, insertionParent } from './insertionState'
import {
insertionAnchor,
insertionParent,
resetInsertionState,
} from './insertionState'
import { isHydrating, locateHydrationNode } from './dom/hydration'

export type RawSlots = Record<string, VaporSlot> & {
Expand Down Expand Up @@ -96,6 +100,8 @@ export function createSlot(
const _insertionAnchor = insertionAnchor
if (isHydrating) {
locateHydrationNode()
} else {
resetInsertionState()
}

const instance = currentInstance as VaporComponentInstance
Expand Down