diff --git a/packages/runtime-core/__tests__/hydration.spec.ts b/packages/runtime-core/__tests__/hydration.spec.ts
index fa89631d201..0114e41e505 100644
--- a/packages/runtime-core/__tests__/hydration.spec.ts
+++ b/packages/runtime-core/__tests__/hydration.spec.ts
@@ -699,4 +699,44 @@ describe('SSR hydration', () => {
expect(`Hydration children mismatch`).toHaveBeenWarned()
})
})
+
+ test('sets and removes internal hydration flag', async () => {
+ const checkHydration = jest.fn()
+
+ const container = document.createElement('div')
+ container.innerHTML = '
foo
'
+
+ const visible = ref(true)
+ const component = defineComponent({
+ render: () => h('div', 'foo'),
+ created() {
+ checkHydration(this.$.isHydrating)
+ },
+ beforeMount() {
+ checkHydration(this.$.isHydrating)
+ },
+ mounted() {
+ checkHydration(this.$.isHydrating)
+ }
+ })
+ const app = createSSRApp({
+ render: () => (visible.value ? h(component) : null)
+ })
+
+ app.mount(container)
+
+ visible.value = false
+ await nextTick()
+ visible.value = true
+ await nextTick()
+
+ expect(checkHydration.mock.calls).toMatchObject([
+ [true],
+ [true],
+ [true],
+ [false],
+ [false],
+ [false]
+ ])
+ })
})
diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts
index 0bc928911e5..5a8461d6ad7 100644
--- a/packages/runtime-core/src/component.ts
+++ b/packages/runtime-core/src/component.ts
@@ -297,6 +297,7 @@ export interface ComponentInternalInstance {
isMounted: boolean
isUnmounted: boolean
isDeactivated: boolean
+ isHydrating: boolean
/**
* @internal
*/
@@ -407,6 +408,7 @@ export function createComponentInstance(
isMounted: false,
isUnmounted: false,
isDeactivated: false,
+ isHydrating: false,
bc: null,
c: null,
bm: null,
diff --git a/packages/runtime-core/src/hydration.ts b/packages/runtime-core/src/hydration.ts
index c2d13a1986d..c9cf6953d0d 100644
--- a/packages/runtime-core/src/hydration.ts
+++ b/packages/runtime-core/src/hydration.ts
@@ -180,7 +180,8 @@ export function createHydrationFunctions(
parentComponent,
parentSuspense,
isSVGContainer(container),
- optimized
+ optimized,
+ true
)
}
// async component
diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts
index cae1ffe57c1..1b767979f9a 100644
--- a/packages/runtime-core/src/renderer.ts
+++ b/packages/runtime-core/src/renderer.ts
@@ -232,7 +232,8 @@ export type MountComponentFn = (
parentComponent: ComponentInternalInstance | null,
parentSuspense: SuspenseBoundary | null,
isSVG: boolean,
- optimized: boolean
+ optimized: boolean,
+ hydrating?: boolean
) => void
type ProcessTextOrCommentFn = (
@@ -1178,7 +1179,8 @@ function baseCreateRenderer(
parentComponent,
parentSuspense,
isSVG,
- optimized
+ optimized,
+ hydrating = false
) => {
const instance: ComponentInternalInstance = (initialVNode.component = createComponentInstance(
initialVNode,
@@ -1186,6 +1188,8 @@ function baseCreateRenderer(
parentSuspense
))
+ instance.isHydrating = hydrating
+
if (__DEV__ && instance.type.__hmrId) {
registerHMR(instance)
}
@@ -1352,6 +1356,7 @@ function baseCreateRenderer(
if ((vnodeHook = props && props.onVnodeMounted)) {
queuePostRenderEffect(() => {
invokeVNodeHook(vnodeHook!, parent, initialVNode)
+ instance.isHydrating = false
}, parentSuspense)
}
// activated hook for keep-alive roots.