fix(hydration): ensure hydrated event listeners have bound instance (#4529)
fix #4479
This commit is contained in:
parent
d8a36d0198
commit
58b1fa5ed1
@ -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() {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user