Higher-Order Components in Vue.js


Higher-Order Components are the concept of Higher-Order Functions applied to Component.
“A higher-order function is a function that operates on other functions. That is, it takes functions as inputs and/or returns them as outputs.”
Like so, a higher-order component is a component that operates on other component.

Why not just use Slots in Vue?

Slots will make a “room” in your component so content can be injected in it. The logic of the content injected is not placed in the Slot component, instead, it remains on its parent.

The goal here is to create a new component based (inherited) on another component.

I had the component below and I wanted to change the <style> and <template> content and reuse the <script>. I could use v-if and have everything in a single component, right? Yeah, I know. The thing is that for me that’s not a good approach. The <script> can remain the same, but all the rest is waaaaay different. So… Why not apply the concept of a higher-order function in a component?

Let’s get to the point, shall we?

So here is the Component I created (ProductItem.vue):

And here is the Higher-Order Component (InlinedProduct.vue):

That approach is very easy to apply in any Vue.js project you might have. As you can see, you can import only the methods and objects you want from a specific component. I could easily add more data to it or omit some of the imports.

Easy to use and very straight forward. Can you feel the power of this thing?

Special thanks to:

Luiz Vinicius (for the code fix);
Fábio Vedovelli (for enriching this article with a great question);
Dan Abramov (for his article)!

You can stop reading right here.

But… Why not just use mixins instead?

According to Sebastian Markbåge, from React team:

To be clear, mixins is an escape hatch to work around reusability limitations in the system. It’s not idiomatic React. Making composition easier is a higher priority than making arbitrary mixins work. I’ll focus on making composition easier so we can get rid of mixins.

Don't get me wrong! I do use mixins. I just think that Sebastian thinking has a point and why not make use of this extend property on Vue.js?