Skip to content

Commit

Permalink
fix(hydration): ensure hydrated event listeners have bound instance (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ygj6 committed Sep 21, 2021
1 parent d8a36d0 commit 58b1fa5
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 2 deletions.
54 changes: 54 additions & 0 deletions packages/runtime-core/__tests__/hydration.spec.ts
Expand Up @@ -461,6 +461,60 @@ describe('SSR hydration', () => {
expect(text.textContent).toBe('bye')
})

test('handle click error in ssr mode', async () => {
const App = {
setup() {
const throwError = () => {
throw new Error('Sentry Error')
}
return { throwError }
},
template: `
<div>
<button class="parent-click" @click="throwError">click me</button>
</div>`
}

const container = document.createElement('div')
// server render
container.innerHTML = await renderToString(h(App))
// hydrate
const app = createSSRApp(App)
const handler = (app.config.errorHandler = jest.fn())
app.mount(container)
// assert interactions
// parent button click
triggerEvent('click', container.querySelector('.parent-click')!)
expect(handler).toHaveBeenCalled()
})

test('handle blur error in ssr mode', async () => {
const App = {
setup() {
const throwError = () => {
throw new Error('Sentry Error')
}
return { throwError }
},
template: `
<div>
<input class="parent-click" @blur="throwError"/>
</div>`
}

const container = document.createElement('div')
// server render
container.innerHTML = await renderToString(h(App))
// hydrate
const app = createSSRApp(App)
const handler = (app.config.errorHandler = jest.fn())
app.mount(container)
// assert interactions
// parent blur event
triggerEvent('blur', container.querySelector('.parent-click')!)
expect(handler).toHaveBeenCalled()
})

test('Suspense', async () => {
const AsyncChild = {
async setup() {
Expand Down
20 changes: 18 additions & 2 deletions packages/runtime-core/src/hydration.ts
Expand Up @@ -287,13 +287,29 @@ export function createHydrationFunctions(
(forcePatchValue && key.endsWith('value')) ||
(isOn(key) && !isReservedProp(key))
) {
patchProp(el, key, null, props[key])
patchProp(
el,
key,
null,
props[key],
false,
undefined,
parentComponent
)
}
}
} else if (props.onClick) {
// Fast path for click listeners (which is most often) to avoid
// iterating through props.
patchProp(el, 'onClick', null, props.onClick)
patchProp(
el,
'onClick',
null,
props.onClick,
false,
undefined,
parentComponent
)
}
}
// vnode / directive hooks
Expand Down

0 comments on commit 58b1fa5

Please sign in to comment.