Skip to content

Commit d398023

Browse files
committed
functional components
1 parent 41e4647 commit d398023

File tree

3 files changed

+45
-4
lines changed

3 files changed

+45
-4
lines changed

src/core/vdom/create-component.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ export function createComponent (
5151
data = data || {}
5252

5353
// merge component management hooks onto the placeholder node
54-
mergeHooks(data)
54+
// only need to do this if this is not a functional component
55+
if (!Ctor.options.functional) {
56+
mergeHooks(data)
57+
}
5558

5659
// extract props
5760
const propsData = extractProps(data, Ctor)

src/core/vdom/create-element.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ import { warn, resolveAsset } from '../util/index'
1010
export function renderElementWithChildren (
1111
vnode: VNode | void,
1212
children: VNodeChildren | void
13-
): VNode | void {
13+
): VNode | Array<VNode> | void {
1414
if (vnode) {
15-
if (vnode.componentOptions) {
15+
const componentOptions = vnode.componentOptions
16+
if (componentOptions) {
1617
if (process.env.NODE_ENV !== 'production' &&
1718
children && typeof children !== 'function') {
1819
warn(
@@ -21,8 +22,21 @@ export function renderElementWithChildren (
2122
'dependencies and optimizes re-rendering.'
2223
)
2324
}
24-
vnode.componentOptions.children = children
25+
const CtorOptions = componentOptions.Ctor.options
26+
// functional component
27+
if (CtorOptions.functional) {
28+
return CtorOptions.render.call(
29+
null,
30+
componentOptions.parent.$createElement, // h
31+
componentOptions.propsData || {}, // props
32+
normalizeChildren(children) // children
33+
)
34+
} else {
35+
// normal component
36+
componentOptions.children = children
37+
}
2538
} else {
39+
// normal element
2640
vnode.setChildren(normalizeChildren(children))
2741
}
2842
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import Vue from 'vue'
2+
3+
describe('Options functional', () => {
4+
it('should work', done => {
5+
const vm = new Vue({
6+
data: { test: 'foo' },
7+
template: '<div><wrap :msg="test">bar</wrap></div>',
8+
components: {
9+
wrap: {
10+
functional: true,
11+
props: ['msg'],
12+
render (h, props, children) {
13+
return h('div', null, [props.msg, ' '].concat(children))
14+
}
15+
}
16+
}
17+
}).$mount()
18+
expect(vm.$el.innerHTML).toBe('<div>foo bar</div>')
19+
vm.test = 'qux'
20+
waitForUpdate(() => {
21+
expect(vm.$el.innerHTML).toBe('<div>qux bar</div>')
22+
}).then(done)
23+
})
24+
})

0 commit comments

Comments
 (0)