Professional Documents
Culture Documents
Functional Components
In the previous lesson we learned how to create render functions. With this new super power there are
two patterns you can use. The first, which we’ll dive into this lesson, is a functional component which
allows you to:
You could think of it like a Component on a diet. Perhaps we want a custom header just for
presentational logic and we decide to write it using a render function:
<div id="app">
<big-topic>
Hiking Boots
</big-topic>
</div>
<script src="vue.js"></script>
<script>
Vue.component('big-topic', {
render(h) {
return h('h1', 'Topic: ' + this.$slots.default)
}
})
new Vue({
el: '#app'
})
</script>
Using a normal Component for this presentational Component is a little overkill. This is where
functional components start to shine:
https://www.vuemastery.com/courses/advanced-components/functional-components 1/6
19/4/2020 Functional Components - Advanced Components | Vue Mastery
A Functional Component:
Can’t have its own data, computed properties, watchers, lifecycle events, or methods.
Can’t have a template, unless that template is precompiled from a single-file component.
That’s why we used a render function above.
Can be passed things, like props, attributes, events, and slots.
Returns a VNode or an array of VNodes from a render function. Unlike a normal component
that has to have a single root VNode, it can return an array of VNodes.
As you might imagine (without less functionality) a functional component is a little faster. We can make
a functional component by simply adding the option:
Vue.component('big-topic', {
functional: true, // <-----
render(h, context) { // Notice the new context parameter
return h('h1', context.slots().default)
}
})
Notice how we now use the context parameter to access slots? This context argument is how
we get access to to things like props, children, data, parent, listeners, and slots inside a functional
component since we no longer can use this . The official Vue documentation goes into more detail.
If we’re using Vue’s single file components we can declare a functional components at the template
level. Here is the above example as a single file component:
<template functional>
<h1>
<slot></slot>
</h1>
</template>
Yes, that could be the ONLY content in your .vue file. No export default, no props, no data, no
methods, and it will just render out the template. This is great for presentational templates.
https://www.vuemastery.com/courses/advanced-components/functional-components 2/6
19/4/2020 Functional Components - Advanced Components | Vue Mastery
Functional components are great to use when you need a way of programmatically delegating to a
specific component. The Vue.js documentation has a great example I’d like to walk you through,
simplified first.
Let’s say you want to create a SmartTable component. If the list passed in is Empty render using
one component, but if it’s not Empty use another component.
The SmartTable component only needs to know how to delegate, it doesn’t have to be very smart,
so it’s going to be a functional component.
<div id="app">
<smart-table :items='vehicles'>
</div>
<script src="vue.js"></script>
<script>
const EmptyTable = {
template: `<h1>Nothing Here</h1>`
}
const NormalTable = { // Normally this would be more complex
template: `<h1>Normal Table</h1>`
}
Vue.component('smart-table', {
functional: true,
props: { items: { type: Array } },
render(h, context) {
if (context.props.items.length > 0 ) { // Delegate
return h(NormalTable, context.data, context.children)
} else {
return h(EmptyTable, context.data, context.children)
https://www.vuemastery.com/courses/advanced-components/functional-components 3/6
19/4/2020 Functional Components - Advanced Components | Vue Mastery
}
}
})
new Vue({
el: '#app',
data: {
vehicles: [ 'Fiat', 'Toyota', 'BMW' ]
}
})
</script>
As you might expect, when the vehicles Array is empty we see the EmptyTable, and when it has one
or more item it displays the Normal Table:
https://www.vuemastery.com/courses/advanced-components/functional-components 4/6
19/4/2020 Functional Components - Advanced Components | Vue Mastery
The example in the Vue documentation is a more complex version of what we have above. Instead of
having just two different components to render our list, we have four in our smart-table. Take a read:
Vue.component('smart-list', {
functional: true,
props: {
items: {
type: Array,
required: true
},
isOrdered: Boolean
},
render: function (createElement, context) {
return UnorderedList
}
})
https://www.vuemastery.com/courses/advanced-components/functional-components 5/6
19/4/2020 Functional Components - Advanced Components | Vue Mastery
As you can see, our functional component just wraps around our other four components.
When you need some sort of wrapper or delegating component, and you care about speed, a
functional component might be the best way to go. In our next lesson, we’ll dive back into the Vue.js
source to figure out more internals of the rendering and mounting process.
https://www.vuemastery.com/courses/advanced-components/functional-components 6/6