Back in my day…
On the grand scale, reactive frameworks (and by that I mean declarative, rather than imperative, ala Vue, React, Angular, etc) are young — with jQuery around since 2006 and the first of the reactive frameworks taking off in 2012.
We’ve only had a bit more time with these new frameworks than we’ve had without them (yes I’m aware the internet existed before jQuery, but it was a dark time; you should see my first Geocities website).
Then, on the scale of reactive frameworks themselves, Vue is young — with AngularJS taking off in 2012, React in 2014, (Angular again in 2015, this time without the “JS” in its name 👍), and Vue in 2015.
What’s this history lesson for?
So we as front-end developers might understand the problem I’m tackling in this article — how to build front-end components for others in our organization. We all know how, what, and why we built our own components, modules, classes, etc — but us knowing why we did things doesn’t scale very well beyond, well… an organization of us.
Awkward sentence right? Lots of references to oneself in there — and Skilljar sure isn’t an entire team of front-end developers either. I’m one of two front-end developers working alongside an entire team of back-end devs that may one day have to look at — or worse — implement front end code 😉
So “my” code? That’s also their code.
So how do I make the world a better place then?
Aka not this — let’s call it the
Ok… then what SHOULD I do?
What if I told you that your components don’t need to be overly complicated — that you can write impressive, modern components, that can still be easily understood by all?
At Skilljar, for example, we recently launched a new Vue Datatable component that looks a little something like this —
Implemented with this —
We wrapped up an entire datatable’s worth of complex functionality into what is no more than a regular HTML element with two little filter-children 🤯 (that’s a head explosion emoji if you can’t see it).
And still using only three single file Vue components —
The two filter components,
DatatableCheckboxFilter.vue, are children components designed to be nested within the main
Datatable.vue element via its
How’s this any different than that <search-form> example?
Architectural decisions are always a challenge. You could look at that datatable screenshot and wonder why the search box isn’t its own Vue component, or why the pagination isn’t, or the per-page dropdown, etc— but there’s just not generally a black and white answer. It usually boils down to understanding who’s going to be using your component as well as how it’s going to be used both now and in the future.
I chose not to architect those as separate components because, in my interpretation, they’re really only features that are either on, or off —and so were built to be toggled with an attribute on the
<sj-datatable> element, i.e.
<sj-datatable :hide-features="['search', 'pagination', 'per-page', /* etc */]">).
The filters, however, were going to be dynamic in both number and types — which meant we needed to either pipe some complex object into the component property (rather than an on/off toggle like above), or it was time split filters out into their own components.
Note: If there was only ever going to be one date filter, or one checkbox filter — maybe with some parameters — those probably also could’ve been “features”, but we were going to need anywhere from zero to multiple filters, all with different parameters, depending on the type of data we were loading into each datatable.
I still have no idea what you’re talking about
Our goal here is to —
We want the addition of a new datatable to be as easy as a backend dev building out their own API endpoint and copy/pasting some previous
<sj-datatable> implementation and thinking —
“Oh hey, if I just update the
csv-endpointproperties and… we don’t need filters right now so I’ll delete those — and… I’m done? Heck yeah.”
Because in the world of front-end development, the closer you can make your fancy reactive components look and feel like something commonly understood and framework agnostic — like HTML — the easier you can make everybody’s lives.
Alright, so give me some guidelines or I’m just going to steal your datatable…
No! I believe in you!
First, wrap up enough complex, reusable functionality that you’re actually saving both time and sanity, i.e. don’t rewrite the HTML spec with your own
Instead of this, which (is probably) overly-abstracted and (again, probably) exposes internals not actually meant to be accessible to other devs—
Try rolling everything up into the one component you want to be reused, perhaps with toggles for simple on/off features like the search button. And don’t just nest all those previous custom components inside this component, inside this should probably be regular old HTML.
Second, keep your component’s styles scoped to itself, in a single file Vue component this looks like —
And finally — document, document, document.
The bane of all our collective existences is bad documentation, so if you’re going to go to all the trouble of creating these beautifully reusable custom components for your organization — document them!
Even if the entirety of your documentation is just an example of the component with all the available properties, it’s better than a documentation black hole.
This is what the (minimal) spec for our Vue Datatable looks like —
I mean, uhh… so there you have it!
If you’re another front-end developer working in a primarily back-end dev organization, I’d love to hear how you tackle building components for an audience not necessarily fluent in your framework ✋
¹ Lame footnote
Unfortunately components can’t listen for events emitted by anything in their
<slot> tags, so inside these
<sj-datepicker>'s we can’t emit an
on-date-selected event and listen for it on the
<sj-datatable> component to dynamically update our data.
Interested in learning more about Skilljar? Check us out at https://www.skilljar.com/. We’d love to chat with you if you’re interested in joining the team. You can learn more about open positions at https://www.skilljar.com/about/careers/
Shout out to my coworker Huy Ngo for both being my photographer and proof-reader on this article 👊