Writing highly reusable components
Maximising code reusability among your frontend components goes a long way towards maintainable source code and far less hours cursing yourself 2–3 months later. Ideally, our components should
- Be highly composable
- Have single responsibility
- Share functionality
- Be easier to read
- be unicorns 🦄😂
Over last few years, frontend frameworks have come up with many great ideas to help in our quest to write such components. This post is about one such idea that is although fundamentally the same (atleast according to my current understandings), but is realised via different terminologies in two of the frameworks i happen to use frequently.
The Problem
Say, we need to build an accordion.
While your frontend application can contain these in many different forms, i.e with very different markup, styling etc. They all have this fundamental functionality in common: there’s some head
which when clicked, toggles its associated content
. So among all these different accordions how do you extract this common functionality?
The idea is to extract functionality (logic) from markup. So that you can apply them selectively, in any combination.
Let’ s see how we can do so in Ember and Vue
Ember’s {{yield}} helper
You probably already know what {{yield}}
does. It acts as a placeholder, as to where the content wrapped inside components blocks will be rendered with respect to component’s own template. But it can also be used to share information between a component and its wrapped content.
This functionality, along with Ember’s Contextual Components allows us to write component logic without specifying the entire template right away.
w-blank
: A blank component with template: {{yield}}
component
helper: Let’s you specify component dynamically
Notice how this essentially allows us to share component data with its wrapped content and now we can specify what markup, styling to render at invocation instead of definition.
Now we can write up all those different accordions, without duplicating that toggle
logic
You can play with the twiddle here: https://ember-twiddle.com/b0e076b864633752ea0f95ae95bfe4a1?openFiles=templates.application.hbs%2Ctemplates.components.w-accordion.hbs
Vue’s scoped slots
I already had experience with Ember when I started with Vue. So naturally, I was interested in implementing similar pattern in Vue as well. Much like every other questions I had about Vue, I found my answer in the docs: https://vuejs.org/v2/guide/components-slots.html#Scoped-Slots
Slots
work very similar to yield
in ember, you can even have multiple slots inside a component too by naming them (https://vuejs.org/v2/guide/components-slots.html#Named-Slots)
Let’s see how we can use them for our purpose
Naming slots
allows us to specify multiple blocks
of wrapped content. Scoping
allows to access slotProps
which are basically props
passed to individual slots, which makes lot of sense and aligns with how things work in Vue Components.
I’ve setup an example on CodeSandbox here:
Conclusion
All of this, Is far from latest developments in the respective frameworks, However, I wish somebody told me about this earlier, as this has helped me write highly compose-able, reuse-able and powerful components.
How do you design your components? What are the challenges you face in process? What did/didn’t work for you in the past? Please do write in the comments
About
I’m a Fullstack Web Developer and Mentor at Coding Blocks. I’ve recently joined Twitter, you can find me here: https://twitter.com/D_RedRightHand.