From 84d0d7cd11b0e5fe0686a979d09210f2a233230b Mon Sep 17 00:00:00 2001 From: Herrington Darkholme Date: Tue, 14 Feb 2017 13:00:06 +0800 Subject: [PATCH 1/3] fix #4872, use context agnostic Function constructor check --- src/core/util/props.js | 3 ++- test/ssr/ssr-string.spec.js | 18 ++++++++++++++++++ test/unit/features/options/props.spec.js | 16 ++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/core/util/props.js b/src/core/util/props.js index 88ed0c1c5f0..83ec94a2318 100644 --- a/src/core/util/props.js +++ b/src/core/util/props.js @@ -70,7 +70,8 @@ function getPropDefaultValue (vm: ?Component, prop: PropOptions, key: string): a return vm[key] } // call factory function for non-Function types - return typeof def === 'function' && prop.type !== Function + // a value is Function if its prototype is function even across different execution context + return typeof def === 'function' && (!prop.type || typeof prop.type.prototype !== 'function') ? def.call(vm) : def } diff --git a/test/ssr/ssr-string.spec.js b/test/ssr/ssr-string.spec.js index 9ff2d62047d..13c0a47039c 100644 --- a/test/ssr/ssr-string.spec.js +++ b/test/ssr/ssr-string.spec.js @@ -1,4 +1,5 @@ import Vue from '../../dist/vue.runtime.common.js' +import VM from 'vm' import { createRenderer } from '../../packages/vue-server-renderer' const { renderToString } = createRenderer() @@ -699,6 +700,23 @@ describe('SSR: renderToString', () => { done() }, context) }) + + it('default value Foreign Function', () => { + const FunctionConstructor = VM.runInNewContext('Function') + const func = () => 123 + const vm = new Vue({ + props: { + a: { + type: FunctionConstructor, + default: func + } + }, + propsData: { + a: undefined + } + }) + expect(vm.a).toBe(func) + }) }) function renderVmWithOptions (options, cb) { diff --git a/test/unit/features/options/props.spec.js b/test/unit/features/options/props.spec.js index 50e5e16faf3..95f85fffef4 100644 --- a/test/unit/features/options/props.spec.js +++ b/test/unit/features/options/props.spec.js @@ -98,6 +98,22 @@ describe('Options props', () => { }).then(done) }) + it('default value Function', () => { + const func = () => 132 + const vm = new Vue({ + props: { + a: { + type: Function, + default: func + } + }, + propsData: { + a: undefined + } + }) + expect(vm.a).toBe(func) + }) + it('warn object/array default values', () => { new Vue({ props: { From 4e5ae2548218c7e68a7311dc7f37e79c944731b6 Mon Sep 17 00:00:00 2001 From: Herrington Darkholme Date: Tue, 14 Feb 2017 22:59:12 +0800 Subject: [PATCH 2/3] use getType to check Function Constructor --- src/core/util/props.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/util/props.js b/src/core/util/props.js index 83ec94a2318..5076a3e5fae 100644 --- a/src/core/util/props.js +++ b/src/core/util/props.js @@ -71,7 +71,7 @@ function getPropDefaultValue (vm: ?Component, prop: PropOptions, key: string): a } // call factory function for non-Function types // a value is Function if its prototype is function even across different execution context - return typeof def === 'function' && (!prop.type || typeof prop.type.prototype !== 'function') + return typeof def === 'function' && getType(prop.type) === 'Function' ? def.call(vm) : def } From e164ca5f7acc44fd165a485b640bc96461fa11c3 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 14 Feb 2017 13:40:26 -0500 Subject: [PATCH 3/3] fix negation --- src/core/util/props.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/util/props.js b/src/core/util/props.js index 5076a3e5fae..1790e61dae9 100644 --- a/src/core/util/props.js +++ b/src/core/util/props.js @@ -71,7 +71,7 @@ function getPropDefaultValue (vm: ?Component, prop: PropOptions, key: string): a } // call factory function for non-Function types // a value is Function if its prototype is function even across different execution context - return typeof def === 'function' && getType(prop.type) === 'Function' + return typeof def === 'function' && getType(prop.type) !== 'Function' ? def.call(vm) : def }