Skip to content

Commit

Permalink
fix(hydration): avoid observing non-Element node (#11954)
Browse files Browse the repository at this point in the history
close #11952
  • Loading branch information
linzhe141 committed Sep 20, 2024
1 parent e075dfa commit 7257e6a
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 1 deletion.
1 change: 1 addition & 0 deletions packages/runtime-core/src/hydrationStrategies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const hydrateOnVisible: HydrationStrategyFactory<
}
}, opts)
forEach(el => {
if (!(el instanceof Element)) return
if (elementIsVisibleInViewport(el)) {
hydrate()
ob.disconnect()
Expand Down
8 changes: 7 additions & 1 deletion packages/vue/__tests__/e2e/hydration-strat-visible.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@
<script>
const rootMargin = location.search.match(/rootMargin=(\d+)/)?.[1] ?? 0
const isFragment = location.search.includes('?fragment')
const isVIf = location.search.includes('?v-if')
if (isFragment) {
document.getElementById('app').innerHTML =
`<!--[--><!--[--><span>one</span><!--]--><button>0</button><span>two</span><!--]-->`
} else if (isVIf) {
document.getElementById('app').innerHTML = `<!---->`
}

window.isHydrated = false
Expand All @@ -24,6 +27,7 @@
ref,
onMounted,
hydrateOnVisible,
createCommentVNode,
} = Vue

const Comp = {
Expand All @@ -39,7 +43,9 @@
{ onClick: () => count.value++ },
count.value,
)
if (isFragment) {
if (isVIf) {
return createCommentVNode('v-if', true)
} else if (isFragment) {
return [[h('span', 'one')], button, h('span', 'two')]
} else {
return button
Expand Down
11 changes: 11 additions & 0 deletions packages/vue/__tests__/e2e/hydrationStrategies.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@ describe('async component hydration strategies', () => {
await assertHydrationSuccess()
})

test('visible (root v-if) should not throw error', async () => {
const spy = vi.fn()
const currentPage = page()
currentPage.on('pageerror', spy)
await goToCase('visible', '?v-if')
await page().waitForFunction(() => window.isRootMounted)
expect(await page().evaluate(() => window.isHydrated)).toBe(false)
expect(spy).toBeCalledTimes(0)
currentPage.off('pageerror', spy)
})

test('media query', async () => {
await goToCase('media')
await page().waitForFunction(() => window.isRootMounted)
Expand Down

0 comments on commit 7257e6a

Please sign in to comment.