From 345713ee5b65859cf050b304a793f0740d1e8cea Mon Sep 17 00:00:00 2001 From: Hiroki Osame Date: Mon, 7 May 2018 21:20:01 +0900 Subject: [PATCH 1/4] feat(functional): Support components hash in functional components Adds support for the components hash to be used in functional components fix #7492 --- src/core/vdom/create-functional-component.js | 5 ++++ test/unit/features/options/functional.spec.js | 28 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/core/vdom/create-functional-component.js b/src/core/vdom/create-functional-component.js index efed801db7d..6fb4d085f10 100644 --- a/src/core/vdom/create-functional-component.js +++ b/src/core/vdom/create-functional-component.js @@ -6,6 +6,7 @@ import { resolveInject } from '../instance/inject' import { normalizeChildren } from '../vdom/helpers/normalize-children' import { resolveSlots } from '../instance/render-helpers/resolve-slots' import { installRenderHelpers } from '../instance/render-helpers/index' +import { extend } from 'shared/util' import { isDef, @@ -39,6 +40,10 @@ export function FunctionalRenderContext ( // $flow-disable-line parent = parent._original } + + contextVm.$options = Object.create(contextVm.$options) + contextVm.$options.components = extend(Object.create(contextVm.$options.components), options.components) + const isCompiled = isTrue(options._compiled) const needNormalization = !isCompiled diff --git a/test/unit/features/options/functional.spec.js b/test/unit/features/options/functional.spec.js index 2c6abe95972..972e7a3401f 100644 --- a/test/unit/features/options/functional.spec.js +++ b/test/unit/features/options/functional.spec.js @@ -242,6 +242,34 @@ describe('Options functional', () => { expect(vm.$el.childNodes[1].namespaceURI).toContain('svg') }) + it('should accept components', () => { + const HelloComp = { + template: `
Hello
` + } + + const WorldComp = { + template: `
World
` + } + + const Child = { + functional: true, + components: { + HelloComp + }, + render: h => [h('hello-comp'), h('world-comp')] + } + + const vm = new Vue({ + template: `
`, + components: { + Child, + WorldComp + } + }).$mount() + + expect(vm.$el.innerHTML).toBe('
Hello
World
') + }) + it('should work with render fns compiled from template', done => { // code generated via vue-template-es2015-compiler var render = function (_h, _vm) { From bc6f48126d8d7e9c3e15752bed7d7eef561e735b Mon Sep 17 00:00:00 2001 From: Hiroki Osame Date: Mon, 7 May 2018 21:33:46 +0900 Subject: [PATCH 2/4] feat(functional): inherit parent in both cases --- src/core/vdom/create-functional-component.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/vdom/create-functional-component.js b/src/core/vdom/create-functional-component.js index 6fb4d085f10..42d6cc3cbee 100644 --- a/src/core/vdom/create-functional-component.js +++ b/src/core/vdom/create-functional-component.js @@ -27,20 +27,20 @@ export function FunctionalRenderContext ( const options = Ctor.options // ensure the createElement function in functional components // gets a unique context - this is necessary for correct named slot check - let contextVm + const contextVm = Object.create(parent) if (hasOwn(parent, '_uid')) { - contextVm = Object.create(parent) // $flow-disable-line contextVm._original = parent } else { // the context vm passed in is a functional context as well. // in this case we want to make sure we are able to get a hold to the // real context instance. - contextVm = parent + // $flow-disable-line parent = parent._original } + // support functional components hash contextVm.$options = Object.create(contextVm.$options) contextVm.$options.components = extend(Object.create(contextVm.$options.components), options.components) From 4d808865e0f09820241317d76e84cb9ed3141961 Mon Sep 17 00:00:00 2001 From: Hiroki Osame Date: Mon, 7 May 2018 21:37:46 +0900 Subject: [PATCH 3/4] feat(functional): fallback if no parent components exists --- src/core/vdom/create-functional-component.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/vdom/create-functional-component.js b/src/core/vdom/create-functional-component.js index 42d6cc3cbee..d9f4d6fba69 100644 --- a/src/core/vdom/create-functional-component.js +++ b/src/core/vdom/create-functional-component.js @@ -42,7 +42,7 @@ export function FunctionalRenderContext ( // support functional components hash contextVm.$options = Object.create(contextVm.$options) - contextVm.$options.components = extend(Object.create(contextVm.$options.components), options.components) + contextVm.$options.components = extend(Object.create(contextVm.$options.components || {}), options.components) const isCompiled = isTrue(options._compiled) const needNormalization = !isCompiled From 71f936ec521edf7e3cc77927693a16a708ac68cf Mon Sep 17 00:00:00 2001 From: Xinyu Liu Date: Tue, 8 Jan 2019 17:24:04 +0800 Subject: [PATCH 4/4] chore(types): add components option for functional --- types/options.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/types/options.d.ts b/types/options.d.ts index cc58affe6a1..6710a0bf247 100644 --- a/types/options.d.ts +++ b/types/options.d.ts @@ -113,6 +113,7 @@ export interface FunctionalComponentOptions | AsyncComponent }; render?(this: undefined, createElement: CreateElement, context: RenderContext): VNode; }