Przeglądaj źródła

feat(runtime-core): skip emit warn if has equivalent onXXX prop

Evan You 6 lat temu
rodzic
commit
0709380c5f

+ 18 - 2
packages/runtime-core/__tests__/componentEmits.spec.ts

@@ -92,7 +92,7 @@ describe('component: emit', () => {
     })
     render(h(Foo), nodeOps.createElement('div'))
     expect(
-      `Component emitted event "bar" but it is not declared`
+      `Component emitted event "bar" but it is neither declared`
     ).toHaveBeenWarned()
   })
 
@@ -109,10 +109,26 @@ describe('component: emit', () => {
     })
     render(h(Foo), nodeOps.createElement('div'))
     expect(
-      `Component emitted event "bar" but it is not declared`
+      `Component emitted event "bar" but it is neither declared`
     ).toHaveBeenWarned()
   })
 
+  test('should not warn if has equivalent onXXX prop', () => {
+    const Foo = defineComponent({
+      props: ['onFoo'],
+      emits: [],
+      render() {},
+      created() {
+        // @ts-ignore
+        this.$emit('foo')
+      }
+    })
+    render(h(Foo), nodeOps.createElement('div'))
+    expect(
+      `Component emitted event "bar" but it is neither declared`
+    ).not.toHaveBeenWarned()
+  })
+
   test('validator warning', () => {
     const Foo = defineComponent({
       emits: {

+ 8 - 4
packages/runtime-core/src/componentEmits.ts

@@ -11,6 +11,7 @@ import {
 import { ComponentInternalInstance } from './component'
 import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling'
 import { warn } from './warning'
+import { normalizePropsOptions } from './componentProps'
 
 export type ObjectEmitsOptions = Record<
   string,
@@ -48,10 +49,13 @@ export function emit(
     const options = normalizeEmitsOptions(instance.type.emits)
     if (options) {
       if (!(event in options)) {
-        warn(
-          `Component emitted event "${event}" but it is not declared in the ` +
-            `emits option.`
-        )
+        const propsOptions = normalizePropsOptions(instance.type.props)[0]
+        if (!propsOptions || !(`on` + capitalize(event) in propsOptions)) {
+          warn(
+            `Component emitted event "${event}" but it is neither declared in ` +
+              `the emits option nor as an "on${capitalize(event)}" prop.`
+          )
+        }
       } else {
         const validator = options[event]
         if (isFunction(validator)) {