From 27ccf0a03b135cc19ad6b56e34548d19bc9d4b71 Mon Sep 17 00:00:00 2001 From: yaodingyd Date: Fri, 13 Apr 2018 17:43:57 -0400 Subject: [PATCH 1/4] feat: add warning in dev mode when method is not function #8017 --- src/core/instance/state.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/instance/state.js b/src/core/instance/state.js index 326f7f36bf7..812034e2cf1 100644 --- a/src/core/instance/state.js +++ b/src/core/instance/state.js @@ -273,6 +273,11 @@ function initMethods (vm: Component, methods: Object) { `Avoid defining component methods that start with _ or $.` ) } + if (typeof methods[key] !== 'function') { + warn( + `Method "${key}" should be a function.` + ) + } } vm[key] = methods[key] == null ? noop : bind(methods[key], vm) } From 3a7fd7281ec667e05bf972738b2cb41217d68244 Mon Sep 17 00:00:00 2001 From: yaodingyd Date: Fri, 13 Apr 2018 19:17:57 -0400 Subject: [PATCH 2/4] feat: add test case and break for loop if method is not function to avoid runtime error --- src/core/instance/state.js | 3 ++- test/unit/features/options/methods.spec.js | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/core/instance/state.js b/src/core/instance/state.js index 812034e2cf1..a63af335933 100644 --- a/src/core/instance/state.js +++ b/src/core/instance/state.js @@ -273,10 +273,11 @@ function initMethods (vm: Component, methods: Object) { `Avoid defining component methods that start with _ or $.` ) } - if (typeof methods[key] !== 'function') { + if (methods[key] != null && typeof methods[key] !== 'function') { warn( `Method "${key}" should be a function.` ) + break } } vm[key] = methods[key] == null ? noop : bind(methods[key], vm) diff --git a/test/unit/features/options/methods.spec.js b/test/unit/features/options/methods.spec.js index 34f9ee88fc6..7c1433d3678 100644 --- a/test/unit/features/options/methods.spec.js +++ b/test/unit/features/options/methods.spec.js @@ -48,4 +48,13 @@ describe('Options methods', () => { }) expect(`Method "_update" conflicts with an existing Vue instance method`).toHaveBeenWarned() }) + + it('should warn if method is not a function', () => { + new Vue({ + methods: { + notAFunction: {} + } + }) + expect(`Method "notAFunction" should be a function`).toHaveBeenWarned() + }) }) From 27444633be631b84edfd69f6935c8914ac06b7f2 Mon Sep 17 00:00:00 2001 From: yaodingyd Date: Sat, 14 Apr 2018 10:09:39 -0400 Subject: [PATCH 3/4] feat: move up if block and set it to null if method is not a function --- src/core/instance/state.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/core/instance/state.js b/src/core/instance/state.js index a63af335933..d58eb883aae 100644 --- a/src/core/instance/state.js +++ b/src/core/instance/state.js @@ -260,6 +260,11 @@ function initMethods (vm: Component, methods: Object) { `Did you reference the function correctly?`, vm ) + } else if (typeof methods[key] !== 'function') { + warn( + `Method "${key}" should be a function.` + ) + methods[key] = null } if (props && hasOwn(props, key)) { warn( @@ -273,12 +278,6 @@ function initMethods (vm: Component, methods: Object) { `Avoid defining component methods that start with _ or $.` ) } - if (methods[key] != null && typeof methods[key] !== 'function') { - warn( - `Method "${key}" should be a function.` - ) - break - } } vm[key] = methods[key] == null ? noop : bind(methods[key], vm) } From 316c9df0bbdd41260c0c6efca43d50c451a85e36 Mon Sep 17 00:00:00 2001 From: Yao Ding Date: Thu, 8 Nov 2018 09:09:20 -0500 Subject: [PATCH 4/4] remove unnecessary string template --- test/unit/features/options/methods.spec.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/unit/features/options/methods.spec.js b/test/unit/features/options/methods.spec.js index 7c1433d3678..b9a10a5d7d9 100644 --- a/test/unit/features/options/methods.spec.js +++ b/test/unit/features/options/methods.spec.js @@ -25,7 +25,7 @@ describe('Options methods', () => { hello: undefined } }) - expect(`Method "hello" has an undefined value in the component definition`).toHaveBeenWarned() + expect('Method "hello" has an undefined value in the component definition').toHaveBeenWarned() }) it('should warn methods conflicting with data', () => { @@ -37,7 +37,7 @@ describe('Options methods', () => { foo () {} } }) - expect(`Method "foo" has already been defined as a data property`).toHaveBeenWarned() + expect('Method "foo" has already been defined as a data property').toHaveBeenWarned() }) it('should warn methods conflicting with internal methods', () => { @@ -46,7 +46,7 @@ describe('Options methods', () => { _update () {} } }) - expect(`Method "_update" conflicts with an existing Vue instance method`).toHaveBeenWarned() + expect('Method "_update" conflicts with an existing Vue instance method').toHaveBeenWarned() }) it('should warn if method is not a function', () => { @@ -55,6 +55,6 @@ describe('Options methods', () => { notAFunction: {} } }) - expect(`Method "notAFunction" should be a function`).toHaveBeenWarned() + expect('Method "notAFunction" should be a function').toHaveBeenWarned() }) })