@@ -18,6 +18,7 @@ import { PatchFlags, ShapeFlags, isOn, isModelListener } from '@vue/shared'
18
18
import { warn } from './warning'
19
19
import { isHmrUpdating } from './hmr'
20
20
import { NormalizedProps } from './componentProps'
21
+ import { isEmitListener } from './componentEmits'
21
22
22
23
// mark the current rendering instance for asset resolution (e.g.
23
24
// resolveComponent, resolveDirective) during render
@@ -290,8 +291,9 @@ export function shouldUpdateComponent(
290
291
nextVNode : VNode ,
291
292
optimized ?: boolean
292
293
) : boolean {
293
- const { props : prevProps , children : prevChildren } = prevVNode
294
+ const { props : prevProps , children : prevChildren , component } = prevVNode
294
295
const { props : nextProps , children : nextChildren , patchFlag } = nextVNode
296
+ const emits = component ! . emitsOptions
295
297
296
298
// Parent component's render function was hot-updated. Since this may have
297
299
// caused the child component's slots content to have changed, we need to
@@ -316,12 +318,15 @@ export function shouldUpdateComponent(
316
318
return ! ! nextProps
317
319
}
318
320
// presence of this flag indicates props are always non-null
319
- return hasPropsChanged ( prevProps , nextProps ! )
321
+ return hasPropsChanged ( prevProps , nextProps ! , emits )
320
322
} else if ( patchFlag & PatchFlags . PROPS ) {
321
323
const dynamicProps = nextVNode . dynamicProps !
322
324
for ( let i = 0 ; i < dynamicProps . length ; i ++ ) {
323
325
const key = dynamicProps [ i ]
324
- if ( nextProps ! [ key ] !== prevProps ! [ key ] ) {
326
+ if (
327
+ nextProps ! [ key ] !== prevProps ! [ key ] &&
328
+ ! isEmitListener ( emits , key )
329
+ ) {
325
330
return true
326
331
}
327
332
}
@@ -343,20 +348,27 @@ export function shouldUpdateComponent(
343
348
if ( ! nextProps ) {
344
349
return true
345
350
}
346
- return hasPropsChanged ( prevProps , nextProps )
351
+ return hasPropsChanged ( prevProps , nextProps , emits )
347
352
}
348
353
349
354
return false
350
355
}
351
356
352
- function hasPropsChanged ( prevProps : Data , nextProps : Data ) : boolean {
357
+ function hasPropsChanged (
358
+ prevProps : Data ,
359
+ nextProps : Data ,
360
+ emitsOptions : ComponentInternalInstance [ 'emitsOptions' ]
361
+ ) : boolean {
353
362
const nextKeys = Object . keys ( nextProps )
354
363
if ( nextKeys . length !== Object . keys ( prevProps ) . length ) {
355
364
return true
356
365
}
357
366
for ( let i = 0 ; i < nextKeys . length ; i ++ ) {
358
367
const key = nextKeys [ i ]
359
- if ( nextProps [ key ] !== prevProps [ key ] ) {
368
+ if (
369
+ nextProps [ key ] !== prevProps [ key ] &&
370
+ ! isEmitListener ( emitsOptions , key )
371
+ ) {
360
372
return true
361
373
}
362
374
}
0 commit comments