From 20da7a6af29cfd7471d476921ac206dc881fb003 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sat, 21 Nov 2020 11:38:30 +0800 Subject: [PATCH 1/8] fix(runtime-core): skip apply mixins if mixinOption is empty --- packages/runtime-core/src/apiCreateApp.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/runtime-core/src/apiCreateApp.ts b/packages/runtime-core/src/apiCreateApp.ts index bcb2fec1c32..d9b0f24baf4 100644 --- a/packages/runtime-core/src/apiCreateApp.ts +++ b/packages/runtime-core/src/apiCreateApp.ts @@ -176,6 +176,11 @@ export function createAppAPI( mixin(mixin: ComponentOptions) { if (__FEATURE_OPTIONS_API__) { + // #2651 + if (Object.keys(mixin).length === 0) { + return app + } + if (!context.mixins.includes(mixin)) { context.mixins.push(mixin) // global mixin with props/emits de-optimizes props/emits From c22467e9477c7a03662e7794e2d3d43125135da8 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sat, 21 Nov 2020 13:17:55 +0800 Subject: [PATCH 2/8] fix(runtime-core): if raw is undefined should return null --- packages/runtime-core/src/apiCreateApp.ts | 8 ++++---- packages/runtime-core/src/componentEmits.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/runtime-core/src/apiCreateApp.ts b/packages/runtime-core/src/apiCreateApp.ts index d9b0f24baf4..a72446a3dee 100644 --- a/packages/runtime-core/src/apiCreateApp.ts +++ b/packages/runtime-core/src/apiCreateApp.ts @@ -176,10 +176,10 @@ export function createAppAPI( mixin(mixin: ComponentOptions) { if (__FEATURE_OPTIONS_API__) { - // #2651 - if (Object.keys(mixin).length === 0) { - return app - } + // // #2651 + // if (Object.keys(mixin).length === 0) { + // return app + // } if (!context.mixins.includes(mixin)) { context.mixins.push(mixin) diff --git a/packages/runtime-core/src/componentEmits.ts b/packages/runtime-core/src/componentEmits.ts index 6b9e505de62..393643bec61 100644 --- a/packages/runtime-core/src/componentEmits.ts +++ b/packages/runtime-core/src/componentEmits.ts @@ -188,7 +188,7 @@ export function normalizeEmitsOptions( } else { extend(normalized, raw) } - return (comp.__emits = normalized) + return (comp.__emits = raw ? normalized : null) } // Check if an incoming prop key is a declared emit event listener. From cfc9d6a79fe64ce8eed3e2d516d4bb9959e31317 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sat, 21 Nov 2020 13:19:28 +0800 Subject: [PATCH 3/8] fix(runtime-core): if raw is undefined should return null --- packages/runtime-core/src/apiCreateApp.ts | 5 ----- packages/runtime-core/src/componentEmits.ts | 1 + 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/runtime-core/src/apiCreateApp.ts b/packages/runtime-core/src/apiCreateApp.ts index a72446a3dee..bcb2fec1c32 100644 --- a/packages/runtime-core/src/apiCreateApp.ts +++ b/packages/runtime-core/src/apiCreateApp.ts @@ -176,11 +176,6 @@ export function createAppAPI( mixin(mixin: ComponentOptions) { if (__FEATURE_OPTIONS_API__) { - // // #2651 - // if (Object.keys(mixin).length === 0) { - // return app - // } - if (!context.mixins.includes(mixin)) { context.mixins.push(mixin) // global mixin with props/emits de-optimizes props/emits diff --git a/packages/runtime-core/src/componentEmits.ts b/packages/runtime-core/src/componentEmits.ts index 393643bec61..a1a82fd5ab9 100644 --- a/packages/runtime-core/src/componentEmits.ts +++ b/packages/runtime-core/src/componentEmits.ts @@ -188,6 +188,7 @@ export function normalizeEmitsOptions( } else { extend(normalized, raw) } + // #2651 if raw is undefined should return null return (comp.__emits = raw ? normalized : null) } From 8798660e64de2c832c3fc358f856c61d251f335c Mon Sep 17 00:00:00 2001 From: daiwei Date: Sat, 21 Nov 2020 13:30:33 +0800 Subject: [PATCH 4/8] fix(runtime-core): if normalized is empty should return null --- packages/runtime-core/src/componentEmits.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/runtime-core/src/componentEmits.ts b/packages/runtime-core/src/componentEmits.ts index a1a82fd5ab9..e610246e38f 100644 --- a/packages/runtime-core/src/componentEmits.ts +++ b/packages/runtime-core/src/componentEmits.ts @@ -188,8 +188,9 @@ export function normalizeEmitsOptions( } else { extend(normalized, raw) } - // #2651 if raw is undefined should return null - return (comp.__emits = raw ? normalized : null) + // #2651 if normalized is empty should return null + return (comp.__emits = + Object.keys(normalized).length === 0 ? null : normalized) } // Check if an incoming prop key is a declared emit event listener. From ac6936274bd6ba4da620754845408284fbc0be2a Mon Sep 17 00:00:00 2001 From: daiwei Date: Sat, 21 Nov 2020 13:39:35 +0800 Subject: [PATCH 5/8] fix(runtime-core): if normalized is empty should return null --- packages/runtime-core/src/componentEmits.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/runtime-core/src/componentEmits.ts b/packages/runtime-core/src/componentEmits.ts index e610246e38f..4a6990cce3e 100644 --- a/packages/runtime-core/src/componentEmits.ts +++ b/packages/runtime-core/src/componentEmits.ts @@ -190,7 +190,7 @@ export function normalizeEmitsOptions( } // #2651 if normalized is empty should return null return (comp.__emits = - Object.keys(normalized).length === 0 ? null : normalized) + !Object.keys(normalized).length && !raw ? null : normalized) } // Check if an incoming prop key is a declared emit event listener. From 25b42b0c81891b175e05b0aa35dac7f3992198b0 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sat, 21 Nov 2020 13:42:11 +0800 Subject: [PATCH 6/8] fix(runtime-core): if normalized is empty and !raw should return null --- packages/runtime-core/src/componentEmits.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/runtime-core/src/componentEmits.ts b/packages/runtime-core/src/componentEmits.ts index 4a6990cce3e..57f8c17cbda 100644 --- a/packages/runtime-core/src/componentEmits.ts +++ b/packages/runtime-core/src/componentEmits.ts @@ -188,7 +188,7 @@ export function normalizeEmitsOptions( } else { extend(normalized, raw) } - // #2651 if normalized is empty should return null + // #2651 if normalized is empty and !raw should return null return (comp.__emits = !Object.keys(normalized).length && !raw ? null : normalized) } From 69533b000f42c33d4fa7a68a866e718cabaee7f2 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sat, 21 Nov 2020 21:23:16 +0800 Subject: [PATCH 7/8] fix: add test case --- .../__tests__/componentEmits.spec.ts | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/packages/runtime-core/__tests__/componentEmits.spec.ts b/packages/runtime-core/__tests__/componentEmits.spec.ts index 53c8d324ea3..1a755a0a6ad 100644 --- a/packages/runtime-core/__tests__/componentEmits.spec.ts +++ b/packages/runtime-core/__tests__/componentEmits.spec.ts @@ -1,7 +1,13 @@ // Note: emits and listener fallthrough is tested in // ./rendererAttrsFallthrough.spec.ts. -import { render, defineComponent, h, nodeOps } from '@vue/runtime-test' +import { + createApp, + render, + defineComponent, + h, + nodeOps +} from '@vue/runtime-test' import { isEmitListener } from '../src/componentEmits' describe('component: emit', () => { @@ -128,6 +134,37 @@ describe('component: emit', () => { ).toHaveBeenWarned() }) + // #2651 + test('should not warning if app mixin an empty object', () => { + const Foo = defineComponent({ + props: ['modelValue'], + render() {}, + created() { + // @ts-ignore + this.$emit('update:modelValue') + } + }) + + const Root = defineComponent({ + components: { + Foo + }, + render() { + return h('div', [h(Foo)]) + } + }) + + const app = createApp(Root) + app.mixin({}) + + const root = nodeOps.createElement('div') + app.mount(root) + + expect( + `Component emitted event "update:modelValue" but it is neither declared` + ).not.toHaveBeenWarned() + }) + test('should not warn if has equivalent onXXX prop', () => { const Foo = defineComponent({ props: ['onFoo'], From 1ddea87c52d661495de4aef69e1d1ba37151a680 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sat, 21 Nov 2020 23:37:51 +0800 Subject: [PATCH 8/8] fix: do not set __props if !raw&&!hasExtends --- packages/runtime-core/src/componentEmits.ts | 10 ++++++---- packages/runtime-core/src/componentProps.ts | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/runtime-core/src/componentEmits.ts b/packages/runtime-core/src/componentEmits.ts index 57f8c17cbda..786c9a1b2f7 100644 --- a/packages/runtime-core/src/componentEmits.ts +++ b/packages/runtime-core/src/componentEmits.ts @@ -169,7 +169,11 @@ export function normalizeEmitsOptions( extend(normalized, normalizeEmitsOptions(raw, appContext, true)) } if (!asMixin && appContext.mixins.length) { - appContext.mixins.forEach(extendEmits) + appContext.mixins.forEach(raw => { + if (Object.keys(raw).length) { + extendEmits(raw) + } + }) } if (comp.extends) { extendEmits(comp.extends) @@ -188,9 +192,7 @@ export function normalizeEmitsOptions( } else { extend(normalized, raw) } - // #2651 if normalized is empty and !raw should return null - return (comp.__emits = - !Object.keys(normalized).length && !raw ? null : normalized) + return (comp.__emits = normalized) } // Check if an incoming prop key is a declared emit event listener. diff --git a/packages/runtime-core/src/componentProps.ts b/packages/runtime-core/src/componentProps.ts index 47b06459505..eff331578de 100644 --- a/packages/runtime-core/src/componentProps.ts +++ b/packages/runtime-core/src/componentProps.ts @@ -378,7 +378,7 @@ export function normalizePropsOptions( } if (!raw && !hasExtends) { - return (comp.__props = EMPTY_ARR as any) + return EMPTY_ARR as any } if (isArray(raw)) {