Functional Components

    • Performance gains from 2.x for functional components are now negligible in 3.x, so we recommend just using stateful components
    • Functional components can only be created using a plain function that receives and context (i.e., slots, attrs, emit)
    • DEPRECATED: functional attribute on single-file component (SFC) <template> is deprecated
    • DEPRECATED: { functional: true } option in components created by functions is deprecated

    For more information, read on!

    In Vue 2, functional components had two primary use cases:

    • to return multiple root nodes

    However, in Vue 3, the performance of stateful components has improved to the point that the difference is negligible. In addition, stateful components now also include the ability to return multiple root nodes.

    As a result, the only remaining use case for functional components is simple components, such as a component to create a dynamic heading. Otherwise, it is recommended to use stateful components as you normally would.

    Or, for those who preferred the <template> in a single-file component:

    Now in Vue 3, all functional components are created with a plain function. In other words, there is no need to define the { functional: true } component option.

    They will receive two arguments: props and context. The context argument is an object that contains a component’s attrs, slots, and emit properties.

    In addition, rather than implicitly provide in a render function, h is now imported globally.

    Single File Components (SFCs)

    In 3.x, the performance difference between stateful and functional components has been drastically reduced and will be insignificant in most use cases. As a result, the migration path for developers using functional on SFCs is to remove the attribute. No additional work required.

    Using our <dynamic-heading> example from before, here is how it would look now.

    The main differences are that:

    1. functional attribute removed on <template>
    2. listeners are now passed as part of $attrs and can be removed

    For more information on the usage of the new functional components and the changes to render functions in general, see: