From: daiwei Date: Sun, 8 Jun 2025 01:04:58 +0000 (+0800) Subject: wip: save X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4aaa69ae496cfb16b90570f27e12d149a50cafb1;p=thirdparty%2Fvuejs%2Fcore.git wip: save --- diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts index e309554f2f..527bead3ec 100644 --- a/packages/runtime-core/src/index.ts +++ b/packages/runtime-core/src/index.ts @@ -505,7 +505,11 @@ export { type VaporInteropInterface } from './apiCreateApp' /** * @internal */ -export { type RendererInternals, MoveType } from './renderer' +export { + type RendererInternals, + MoveType, + getInheritedScopeIds, +} from './renderer' /** * @internal */ diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index 5a18d62a8e..cdf7462449 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -764,30 +764,9 @@ function baseCreateRenderer( hostSetScopeId(el, slotScopeIds[i]) } } - let subTree = parentComponent && parentComponent.subTree - if (subTree) { - if ( - __DEV__ && - subTree.patchFlag > 0 && - subTree.patchFlag & PatchFlags.DEV_ROOT_FRAGMENT - ) { - subTree = - filterSingleRoot(subTree.children as VNodeArrayChildren) || subTree - } - if ( - vnode === subTree || - (isSuspense(subTree.type) && - (subTree.ssContent === vnode || subTree.ssFallback === vnode)) - ) { - const parentVNode = parentComponent!.vnode! - setScopeId( - el, - parentVNode, - parentVNode.scopeId, - parentVNode.slotScopeIds, - parentComponent!.parent, - ) - } + const inheritedScopeIds = getInheritedScopeIds(vnode, parentComponent) + for (let i = 0; i < inheritedScopeIds.length; i++) { + hostSetScopeId(el, inheritedScopeIds[i]) } } @@ -2656,3 +2635,54 @@ function getVaporInterface( } return res! } + +/** + * shared between vdom and vapor + */ +export function getInheritedScopeIds( + vnode: VNode, + parentComponent: GenericComponentInstance | null, +): string[] { + const inheritedScopeIds: string[] = [] + + let currentParent = parentComponent + let currentVNode = vnode + + while (currentParent) { + let subTree = currentParent.subTree + if (!subTree) break + + if ( + __DEV__ && + subTree.patchFlag > 0 && + subTree.patchFlag & PatchFlags.DEV_ROOT_FRAGMENT + ) { + subTree = + filterSingleRoot(subTree.children as VNodeArrayChildren) || subTree + } + + if ( + currentVNode === subTree || + (isSuspense(subTree.type) && + (subTree.ssContent === currentVNode || + subTree.ssFallback === currentVNode)) + ) { + const parentVNode = currentParent.vnode! + + if (parentVNode.scopeId) { + inheritedScopeIds.push(parentVNode.scopeId) + } + + if (parentVNode.slotScopeIds) { + inheritedScopeIds.push(...parentVNode.slotScopeIds) + } + + currentVNode = parentVNode + currentParent = currentParent.parent + } else { + break + } + } + + return inheritedScopeIds +} diff --git a/packages/runtime-vapor/__tests__/scopeId.spec.ts b/packages/runtime-vapor/__tests__/scopeId.spec.ts index 657936352d..827ea501f2 100644 --- a/packages/runtime-vapor/__tests__/scopeId.spec.ts +++ b/packages/runtime-vapor/__tests__/scopeId.spec.ts @@ -321,6 +321,50 @@ describe('vdom interop', () => { ) }) + test('vdom parent > vapor > vapor > vdom child', () => { + const InnerVdomChild = { + __scopeId: 'inner-vdom-child', + setup() { + return () => h('button') + }, + } + + const VaporChild = defineVaporComponent({ + __scopeId: 'vapor-child', + setup() { + return createComponent(InnerVdomChild as any, null, null, true) + }, + }) + + const VaporChild2 = defineVaporComponent({ + __scopeId: 'vapor-child2', + setup() { + return createComponent(VaporChild as any, null, null, true) + }, + }) + + const VdomChild = { + __scopeId: 'vdom-child', + setup() { + return () => h(VaporChild2 as any) + }, + } + + const App = { + __scopeId: 'parent', + setup() { + return () => h(VdomChild) + }, + } + + const root = document.createElement('div') + createApp(App).use(vaporInteropPlugin).mount(root) + + expect(root.innerHTML).toBe( + ``, + ) + }) + test('vdom parent > vapor dynamic child', () => { const VaporChild = defineVaporComponent({ __scopeId: 'vapor-child', @@ -418,7 +462,7 @@ describe('vdom interop', () => { ) }) - test.todo('vapor parent > vdom > vdom > vapor child', () => { + test('vapor parent > vdom > vdom > vapor child', () => { const InnerVaporChild = defineVaporComponent({ __scopeId: 'inner-vapor-child', setup() { diff --git a/packages/runtime-vapor/src/block.ts b/packages/runtime-vapor/src/block.ts index c094642dfc..a67e43543e 100644 --- a/packages/runtime-vapor/src/block.ts +++ b/packages/runtime-vapor/src/block.ts @@ -8,6 +8,7 @@ import { import { createComment, createTextNode } from './dom/node' import { EffectScope, pauseTracking, resetTracking } from '@vue/reactivity' import { isHydrating } from './dom/hydration' +import { getInheritedScopeIds } from '@vue/runtime-dom' export type Block = | Node @@ -213,12 +214,16 @@ export function setComponentScopeId(instance: VaporComponentInstance): void { setScopeId(instance.block, scopeId) } - // vdom parent + // inherit scopeId from vdom parent if ( parent.subTree && (parent.subTree.component as any) === instance && parent.vnode!.scopeId ) { setScopeId(instance.block, parent.vnode!.scopeId) + const scopeIds = getInheritedScopeIds(parent.vnode!, parent.parent) + for (const id of scopeIds) { + setScopeId(instance.block, id) + } } }