Functional Components
Introduction
Our functional Vue 2 Component
<template functional>
<div data-name="image-card" class="text-center">
<div>
<img :src="props.image" :alt="props.title" class="mx-auto" />
</div>
<div>{{ props.title }}</div>
</div>
</template>
<script>
export default {
name: 'ImageCard',
props: {
image: String,
title: String,
},
}
</script>
Migration to a Vue 3 component
- remove the
functional
attribute from the template element. - Change
props
,attrs
, andemit
references to their$
-prefixed counterparts
Our component only uses props, but the changes for attrs
and emit
should be self-explanatory from that.
Vue 3 code:
<template>
<div data-name="image-card" class="text-center">
<div>
<img :src="$props.image" :alt="$props.title" class="mx-auto" />
</div>
<div>{{ $props.title }}</div>
</div>
</template>
<script>
export default {
name: 'ImageCard',
props: {
image: String,
title: String,
},
}
</script>
This is a pretty simple find-and-replace migration, and should work fairly quickly.
Migrating render functions
Your own project might use functional components that were written with render functions. Those could be migrated to normal components as well, following a pattern like the above - the bigger challenge here would be to convert the render function to the new virtualDOM API. You can read more about that in the official Migration guide's chapter on render functions.
Functional components in Vue 3.
there still are functional components in Vue 3, but they are now really "just functions":
import { h } from 'vue'
export function myComponent (props, { attrs, slots, emit }) {
return h('div', { id: props.id }, slots.default())
}
// optional runtime prop definitions
myComponent.props = {
id: String
}
As such, they don't support templates anymore, so you have to write the render functions in plain JS or JSX. There usefulness is also limited, as in Vue 3, the performance advantage of functional components over normal, stateful components, is much smaller.