fix(runtime-core): improve dedupe listeners when attr fallthrough (#4912)
fix #4859
This commit is contained in:
parent
04e5835196
commit
b4eb7e3866
@ -11,7 +11,8 @@ import {
|
|||||||
createBlock,
|
createBlock,
|
||||||
FunctionalComponent,
|
FunctionalComponent,
|
||||||
createCommentVNode,
|
createCommentVNode,
|
||||||
Fragment
|
Fragment,
|
||||||
|
withModifiers
|
||||||
} from '@vue/runtime-dom'
|
} from '@vue/runtime-dom'
|
||||||
import { PatchFlags } from '@vue/shared/src'
|
import { PatchFlags } from '@vue/shared/src'
|
||||||
|
|
||||||
@ -383,6 +384,45 @@ describe('attribute fallthrough', () => {
|
|||||||
expect(`Extraneous non-emits event listeners`).toHaveBeenWarned()
|
expect(`Extraneous non-emits event listeners`).toHaveBeenWarned()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should dedupe same listeners when $attrs is used during render', () => {
|
||||||
|
const click = jest.fn()
|
||||||
|
const count = ref(0)
|
||||||
|
|
||||||
|
function inc() {
|
||||||
|
count.value++
|
||||||
|
click()
|
||||||
|
}
|
||||||
|
|
||||||
|
const Parent = {
|
||||||
|
render() {
|
||||||
|
return h(Child, { onClick: inc })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Child = defineComponent({
|
||||||
|
render() {
|
||||||
|
return h(
|
||||||
|
'div',
|
||||||
|
mergeProps(
|
||||||
|
{
|
||||||
|
onClick: withModifiers(() => {}, ['prevent', 'stop'])
|
||||||
|
},
|
||||||
|
this.$attrs
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const root = document.createElement('div')
|
||||||
|
document.body.appendChild(root)
|
||||||
|
render(h(Parent), root)
|
||||||
|
|
||||||
|
const node = root.children[0] as HTMLElement
|
||||||
|
node.dispatchEvent(new CustomEvent('click'))
|
||||||
|
expect(click).toHaveBeenCalledTimes(1)
|
||||||
|
expect(count.value).toBe(1)
|
||||||
|
})
|
||||||
|
|
||||||
it('should not warn when $attrs is used during render', () => {
|
it('should not warn when $attrs is used during render', () => {
|
||||||
const Parent = {
|
const Parent = {
|
||||||
render() {
|
render() {
|
||||||
|
@ -791,7 +791,10 @@ export function mergeProps(...args: (Data & VNodeProps)[]) {
|
|||||||
} else if (isOn(key)) {
|
} else if (isOn(key)) {
|
||||||
const existing = ret[key]
|
const existing = ret[key]
|
||||||
const incoming = toMerge[key]
|
const incoming = toMerge[key]
|
||||||
if (existing !== incoming) {
|
if (
|
||||||
|
existing !== incoming &&
|
||||||
|
!(isArray(existing) && existing.includes(incoming))
|
||||||
|
) {
|
||||||
ret[key] = existing
|
ret[key] = existing
|
||||||
? [].concat(existing as any, incoming as any)
|
? [].concat(existing as any, incoming as any)
|
||||||
: incoming
|
: incoming
|
||||||
|
Loading…
Reference in New Issue
Block a user