What Are Functional Components?
Functional components are essentially functions that serve as components. For those familiar with Vue.js, functional components are components without internal state, lifecycle hooks, or component instances (no this).
In real-world development, many UI components are purely presentational—detail pages, list views, or display components that only render data passed from parent components without requiring internal state or lifecycle logic. These are ideal candidates for functional components.
Functional Component Example
Here is a functional component that displays a user avatar:
export default {
functional: true,
props: {
userImage: {
type: String
}
},
render(createElement, context) {
const { props } = context
const imageSource = props.userImage || 'fallback-image.svg'
return createElement('img', {
attrs: {
src: imageSource,
alt: 'User profile picture'
}
})
}
}
This avatar component accepts an external image URL and displays a fallback image when none is provided. The example uses Vue's createElement function, which can also be written using JSX syntax.
Why Use Functional Components?
- Performance: Functional components don't require instantiation, have no state, and lack lifecycle methods, making them faster than regular components
- Simplicity: The code structure is more straightforward and easier to maintain
Functional Components vs Regular Components
| Feature | Functional Component | Regular Component |
|---|---|---|
| Instantiation | Not instantiated | Requires instantiation |
this |
Not available (use render context) | Available |
| Lifecycle hooks | Not available | Available |
| Computed properties | Not available | Available |
| Event handling | Use context.listeners |
Use $emit |
ref reference |
Returns DOM element | Returns component instance |
| Props declaration | Optional | Required |
| Undeclared attributes | Auto-resolved as props | Go to $attrs |
Key Differences Explained
- Functional components must declare
functional: truein the component options - Since there's no
this, props and slots are accessed through the render function's second parameter (context) - Functional components cannot emit events to parents; instead, they use
context.listenersto invoke parent-provided handlers - When referencing a functional component via
ref, you get the actual HTML element - Undeclared props in functional components are automatically treated as props, while regular components place them in
$attrs
Using Functional Components Without JSX
Prior to Vue 2.5, functional components required JSX. Later versions support template-based declaration:
<template functional>
<img
:src="props.userImage || 'fallback-image.svg'"
:alt="props.altText || 'Default alt'"
/>
</template>
The template approach allows omitting explicit props declarations—any passed attributes are automatically available through the props object.