From: 三咲智子 Kevin Deng Date: Thu, 14 Nov 2024 17:21:30 +0000 (+0800) Subject: fix(runtime-vapor): scope id for `v-if` X-Git-Tag: v3.6.0-alpha.1~16^2~281 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7f3ca4652389a2420e4112da22db775506056cb6;p=thirdparty%2Fvuejs%2Fcore.git fix(runtime-vapor): scope id for `v-if` --- diff --git a/packages/runtime-vapor/src/apiCreateComponent.ts b/packages/runtime-vapor/src/apiCreateComponent.ts index 581a86079a..df67f17360 100644 --- a/packages/runtime-vapor/src/apiCreateComponent.ts +++ b/packages/runtime-vapor/src/apiCreateComponent.ts @@ -38,6 +38,11 @@ export function createComponent( slots, once, ) + + instance.scopeIds = [...current.scopeIds] + const scopeId = current.type.__scopeId + if (scopeId) instance.scopeIds.push(scopeId) + setupComponent(instance) // register sub-component with current component for lifecycle management diff --git a/packages/runtime-vapor/src/apiRender.ts b/packages/runtime-vapor/src/apiRender.ts index 26a9b98cb7..f173964ba8 100644 --- a/packages/runtime-vapor/src/apiRender.ts +++ b/packages/runtime-vapor/src/apiRender.ts @@ -91,8 +91,17 @@ export function setupComponent(instance: ComponentInternalInstance): void { block = [] } instance.block = block - fallThroughAttrs(instance) - attachScopeId(instance) + + const rootElement = findFirstRootElement(instance) + if (rootElement) { + fallThroughAttrs(instance, rootElement) + + // attach scopeId + for (const id of instance.scopeIds) { + rootElement.setAttribute(id, '') + } + } + return block }) reset() @@ -168,15 +177,19 @@ export function unmountComponent(instance: ComponentInternalInstance): void { flushPostFlushCbs() } -export function attachScopeId(instance: ComponentInternalInstance): void { - const scopeId = instance.type.__scopeId - if (scopeId) { - let blk: Block | null = instance.block - while (blk && componentKey in blk) { - blk = blk.block - if (blk instanceof Element) { - blk.setAttribute(scopeId, '') - } +function findFirstRootElement(instance: ComponentInternalInstance) { + const element = getFirstNode(instance.block) + return element instanceof Element ? element : undefined +} + +function getFirstNode(block: Block | null): Node | undefined { + if (!block || componentKey in block) return + if (block instanceof Node) return block + if (isArray(block)) { + if (block.length === 1) { + return getFirstNode(block[0]) } + } else { + return getFirstNode(block.nodes) } } diff --git a/packages/runtime-vapor/src/component.ts b/packages/runtime-vapor/src/component.ts index fdfcd55f06..9c36c84f53 100644 --- a/packages/runtime-vapor/src/component.ts +++ b/packages/runtime-vapor/src/component.ts @@ -162,6 +162,7 @@ export interface ComponentInternalInstance { provides: Data scope: EffectScope comps: Set + scopeIds: string[] rawProps: NormalizedRawProps propsOptions: NormalizedPropsOptions @@ -293,6 +294,7 @@ export function createComponentInstance( provides: parent ? parent.provides : Object.create(_appContext.provides), type: component, comps: new Set(), + scopeIds: [], // resolved props and emits options rawProps: null!, // set later diff --git a/packages/runtime-vapor/src/componentAttrs.ts b/packages/runtime-vapor/src/componentAttrs.ts index 7807063fba..635b45a7a4 100644 --- a/packages/runtime-vapor/src/componentAttrs.ts +++ b/packages/runtime-vapor/src/componentAttrs.ts @@ -1,14 +1,9 @@ import { camelize, isArray, normalizeClass, normalizeStyle } from '@vue/shared' -import { - type ComponentInternalInstance, - componentKey, - currentInstance, -} from './component' +import { type ComponentInternalInstance, currentInstance } from './component' import { isEmitListener } from './componentEmits' import { type RawProps, walkRawProps } from './componentProps' import { renderEffect } from './renderEffect' import { mergeProp, setDynamicProp } from './dom/prop' -import type { Block } from './apiRender' export function patchAttrs( instance: ComponentInternalInstance, @@ -97,35 +92,20 @@ export function withAttrs(props: RawProps): RawProps { return [attrsGetter, props] } -function getFirstNode(block: Block | undefined): Node | undefined { - if (!block || componentKey in block) return - if (block instanceof Node) return block - if (isArray(block)) { - if (block.length === 1) { - return getFirstNode(block[0]) - } - } else { - return getFirstNode(block.nodes) - } -} - -export function fallThroughAttrs(instance: ComponentInternalInstance): void { +export function fallThroughAttrs( + instance: ComponentInternalInstance, + element: Element, +): void { const { - block, type: { inheritAttrs }, dynamicAttrs, } = instance if ( inheritAttrs === false || - dynamicAttrs === true || // all props as dynamic - !block || - componentKey in block + dynamicAttrs === true // all props as dynamic ) return - const element = getFirstNode(block) - if (!element || !(element instanceof Element)) return - const hasStaticAttrs = dynamicAttrs || dynamicAttrs === false let initial: Record | undefined