What's up?
You may have noticed that recently I've been experimenting with adding sponsors to this newsletter.
Honestly, I'm not sure I like putting them in here.
It's extra work that I don't particularly enjoy, and I have the feeling it doesn't make the newlsetter better for you either. Of course, if it made boatloads of cash so I could focus more time on this then it would be worth it, but that's just not the case...
I'd rather spend that time on writing better tips for you.
— Michael
Props down, events up. That's how your components should communicate — most of the time.
But in rare cases, that just doesn't work.
If you need direct access to the parent component, you can use the instance property $parent
:
// Tight coupling like this is usually a bad ideathis.$parent.methodOnParentComponent();
You can also get direct access to the application root, the very top-most component in the tree, by using $root
. Vue 2 also has $children
, but it was taken out for Vue 3 (please don't use this one).
When would these be useful?
There are a few different scenarios I can think of. Usually when you want to abstract some behaviour and have it work "magically" behind the scenes.
In those cases, you don't want to use props and events to connect up a component. Rather, you use provide
/inject
, $parent
, or $root
, to automatically connect the components and make things happen.
But it's hard to come up with an example where this is the best solution. Using provide
/inject
is almost always the better choice.
The Base Component pattern is one of my favourite ways to make lots of different versions and variants from a single component.
It has a few basic steps:
Here's an example, creating a DisabledButton
variant out of a BaseButton
component:
<!-- DisabledButton.vue --><template><!-- Never forget how to create this disabled button.Package it up using the Base Component pattern. --><BaseButtontype="disabled"disabled><!-- You can't accidentally use the wrong icon now.It's provided here for you --><template #icon><Icon type="disabled" /></template></BaseButton></template>
You can use this pattern in many different ways:
Button
component and hard code a few props to get a DisabledButton
. Now you can just use the DisabledButton
directly without having to fiddle with all the necessary props each time.InfoButton
variant where the icon passed to the Button
is always the same. Now, if you ever need to change the icon (or anything else) you can do it in one place.BaseButton
with all the props, and a Button
that passes on only the most common ones. This is a lot safer, easier to use, and the documentation is easier to read too.I've included more on this pattern in Reusable Components.
Just an hour ago, Marco asked me this very question.
My quick response was: keep it flat and simple, and when things start to get messy, slowly add in folders.
An even better response: Markus wrote a great article on this, and he goes into much more detail and provides some more specific advice.
Read his article here: Vue Project Directory Structure
Automating chaos just gives faster chaos. — Mark Fewster
This is the paradox of abstraction:
Creating a component and reusing it over and over can save you a lot of time.
But if that component is wrong or has a bug, you also multiply that problem over and over 🤦‍♂️
The best way to commit something to long-term memory is to periodically review it, gradually increasing the time between reviews 👨‍🔬
Actually remembering these tips is much more useful than just a quick distraction, so here's a tip from a couple weeks ago to jog your memory.
Aria roles are used to tell a screenreader what an element is for.
This is really important when the native HTML elemen just doesn't exist (eg. roles like toolbar
and alert
) or when you're using a different HTML element for design or technical reasons (eg. wrapping a radio
button to style it).
But please, remember that you should always use the semantic element where you can. This is always the best and most effective solution.
There are six different categories of aria roles:
button
, checkbox
, separator
, tab
, or scrollbar
combobox
and listbox
(these are for dropdown menus), radiogroup
, or tree
article
, presentation
, figure
, feed
, and directory
banner
, main
, navigation
, and region
are roles in this categoryalert
, log
, marquee
, and status
are roles that might update with real-time informationalertdialog
and dialog
are the only two roles in this categoryYou can check out the full list here: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques#roles
p.s. I also have two courses: Reusable Components and Clean Components