First of all: welcome to my blog! This is my first post and I want to greet you and say a big thanks for coming here!
So, let's go forward with the real topic of this post.
Table of Contents
What is a Vue component?
Basically a component is a reusable Vue instance with its own state, props, computed props, methods and lifecycle.
Cool features, right? Yes, they are... But try to ask to yourself: "Do I always really need of all these features? Is it always necessary to have reactive data and the whole component's lifecycle?"
The answer to all these questions is: No, you don't.
Sometimes you just need to have a component whose main gol is to render something.
I know, now you're asking to yourself: "Could I use a normal component to do that?"
The answer is: Yes, you can.
But, now, let me ask you a question: "Why should you use a normal component for doing that when you can use a functional component?"
Functional component
A functional component is, basically, an instanceless component without the lifecycle. Nothing else. It's just a simple function whose goal is to render some data.
For this reason you can also call it presentational component or dumb component.
Since this kind of components don't have instances, they are faster, lighter and rendered once. As you can see I've written lighter because, without the whole lifecyle and the reactivity system, the final bundle is lighter, which means:
- less JavaScript code to parse;
- less memory to handle.
All this stuff gives to your applications better performances and browsers will be grateful to you.
How can I write a functional component?
I'm pretty sure, at this point, you have this question spinning around in your mind. I want to be as clear as possible, so I'll answer you with some code.
What I'm going to do is to code a normal component and transform it into a functional component.
Normal component
<template>
<div class="smart-component">
<span class="smart-component__prop">{{foo}}</span>
<span class="smart-component__prop">{{bar}}</span>
</div>
</template>
<script>
export default {
name: "SmartComponent",
props: {
foo: {
type: String,
required: true
},
bar: {
type: String,
required: false,
default: "Default value"
}
}
};
</script>
Cool, isn't it? But do you know what happen each time the SmartComponent
is instantiated?
Basically Vue creates its instance, adds reactivity and mount the component. All useless stuff, since the SmartComponent
is not going to use reactivity. And, as I've already said, the final bundle will be heavier.
Let's rewrite it in the functional way.
Functional component
<template functional>
<div class="dumb-component">
<span class="dumb-component__prop">{{props.foo}}</span>
<span class="dumb-component__prop">{{props.bar}}</span>
</div>
</template>
<script>
export default {
name: "DumbComponent",
props: {
foo: {
type: String,
required: true
},
bar: {
type: String,
required: false,
default: "Default value"
}
}
};
</script>
That's all. Nothing special. As you can see, I've only changed a couple of things:
- I've added the
functional
keyword to the template block; - I've prepended the
props
keyword tofoo
andbar
props.
The functional keyword
Well, as you can easily guess, the functional
keyword is used to say to Vue: "Hey, I'm going to write a functional component! Don't overload it adding the whole lifecycle and the reactivity; I don't need them!"
The props keyword
Since functional components don't have an instance, the this
keyword will be undefined
. So, to read props, you need to prepend the props
keyword to each prop.
I know, I know... You're asking to yourself: "WTF? I don't see any this
before SmartComponent
props!"
The reason is that Vue automatically binds props
, methods
, computed
and $options
objects to the component instance.
So, basically, in this scenario {{foo}}
and {{bar}}
are short versions of {{this.foo}}
and {{this.bar}}
.
Keep in mind: this works ONLY within the <template>
block; in the <script>
block you MUST put the this
keyword before props, methods, computed and $options, otherwise you'll get an error.
N.B. There is another way to write functional components and it's with the usage of render functions, but I'll write a more detailed post about them.
TL;DR
When you don't need to have a reactive state and the whole component lifecycle, for better performances, you should use functional components.
Follow me on
If you liked the post, you might offer me a โ๏ธ on PayPal. ๐
Top comments (1)
Welcome to DEV!