diff --git a/packages/runtime-core/__tests__/components/BaseTransition.spec.ts b/packages/runtime-core/__tests__/components/BaseTransition.spec.ts
index ccb1ae61720..00562a15260 100644
--- a/packages/runtime-core/__tests__/components/BaseTransition.spec.ts
+++ b/packages/runtime-core/__tests__/components/BaseTransition.spec.ts
@@ -10,7 +10,8 @@ import {
serialize,
VNodeProps,
KeepAlive,
- TestElement
+ TestElement,
+ withScopeId
} from '@vue/runtime-test'
function mount(
@@ -1090,5 +1091,34 @@ describe('BaseTransition', () => {
test('w/ KeepAlive', async () => {
await runTestWithKeepAlive(testInOutBeforeFinish)
})
+
+ // #2892
+ test('should work with slots + scopeId', async () => {
+ const withChildId = withScopeId('foo')
+ const withRootId = withScopeId('root')
+
+ const Child = {
+ render: withChildId(function(this: any) {
+ return h(BaseTransition, null, {
+ default: withChildId(() =>
+ h('div', null, h('div', this.$slots.default()))
+ )
+ })
+ })
+ }
+
+ const App = {
+ render: withRootId(() =>
+ h(Child, null, {
+ default: withRootId(() => h('div'))
+ })
+ )
+ }
+ const root = nodeOps.createElement('div')
+ render(h(App), root)
+ expect(serializeInner(root)).toBe(
+ `
`
+ )
+ })
})
})
diff --git a/packages/runtime-core/__tests__/components/KeepAlive.spec.ts b/packages/runtime-core/__tests__/components/KeepAlive.spec.ts
index 0b3e7f5938a..9eb3b30b23a 100644
--- a/packages/runtime-core/__tests__/components/KeepAlive.spec.ts
+++ b/packages/runtime-core/__tests__/components/KeepAlive.spec.ts
@@ -825,4 +825,32 @@ describe('KeepAlive', () => {
await nextTick()
expect(serializeInner(root)).toBe(`changed
`)
})
+
+ // #2892
+ test('should work with slots + scopeId', async () => {
+ const withChildId = withScopeId('foo')
+ const withRootId = withScopeId('root')
+
+ const Child = {
+ render: withChildId(function(this: any) {
+ return h(KeepAlive, null, {
+ default: withChildId(() =>
+ h('div', null, h('div', this.$slots.default()))
+ )
+ })
+ })
+ }
+
+ const App = {
+ render: withRootId(() =>
+ h(Child, null, {
+ default: withRootId(() => h('div'))
+ })
+ )
+ }
+ render(h(App), root)
+ expect(serializeInner(root)).toBe(
+ ``
+ )
+ })
})
diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts
index da86040d0a1..1d962a79974 100644
--- a/packages/runtime-core/src/renderer.ts
+++ b/packages/runtime-core/src/renderer.ts
@@ -805,13 +805,13 @@ function baseCreateRenderer(
hostSetScopeId(el, scopeId)
}
if (parentComponent) {
- const treeOwnerId = parentComponent.type.__scopeId
+ let subTree = parentComponent.subTree
+ const treeOwnerId = subTree.scopeId
// vnode's own scopeId and the current patched component's scopeId is
// different - this is a slot content node.
if (treeOwnerId && treeOwnerId !== scopeId) {
hostSetScopeId(el, treeOwnerId + '-s')
}
- let subTree = parentComponent.subTree
if (__DEV__ && subTree.type === Fragment) {
subTree =
filterSingleRoot(subTree.children as VNodeArrayChildren) || subTree