🔥 Vue Tips #28: Easily create component variations with the Base Component pattern
Tags: vue, webdev, javascript, tutorial
Published: 2021-10-05 13:45:02

---
title: "🔥 Vue Tips #28: Easily create component variations with the Base Component pattern"
published: true
description: "Accessing parent components, easily creating component variations, structuring a Vue project, and automating chaos."
canonical_url: https://michaelnthiessen.com/weekly-028-september-29/
tags: vue, webdev, javascript, tutorial
series: Vue Tips
---

_This newsletter was sent out to my list on September 29, 2021. [Sign up here](https://michaelnthiessen.com/newsletter) to get emails like this each week!_

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


## 🔥 Directly accessing parent components (and why)

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`:
```js
// Tight coupling like this is usually a bad idea
this.$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.

## 🔥 Easily create component variations with the Base Component pattern

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:

1. Create your base component
1. Wrap it with another component to get a variant of the original
1. Repeat step 2 as many times as you need

Here's an example, creating a `DisabledButton` variant out of a `BaseButton` component:
```html
<!-- DisabledButton.vue -->
<template>
  <!-- Never forget how to create this disabled button.
       Package it up using the Base Component pattern. -->
  <BaseButton
    type="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:
- **Lock down props** — take a `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.
- **Lock down slots** — create an `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.
- **Simplify props** — sometimes components end up with dozens of props, most of which are for edge cases. Create a `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](michaelnthiessen.com/reusable-components).


## 📜 How do you structure a Vue project?

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](https://markus.oberlehner.net/blog/vue-project-directory-structure-keep-it-flat-or-group-by-domain/)


## 💬 Software Quote
_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 🤦‍♂️


## 🧠 Spaced-repetition: Aria roles you didn't know you needed

__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:

1. Widget - roles like `button`, `checkbox`, `separator`, `tab`, or `scrollbar`
1. Composite - roles like `combobox` and `listbox` (these are for dropdown menus), `radiogroup`, or `tree`
1. Document structure - this includes `article`, `presentation`, `figure`, `feed`, and `directory`
1. Landmark - `banner`, `main`, `navigation`, and `region` are roles in this category
1. Live region - `alert`, `log`, `marquee`, and `status` are roles that might update with real-time information
1. Window - `alertdialog` and `dialog` are the only two roles in this category

You can check out the full list here: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques#roles

## Exclusive tips and insights every week

Join 8135 other Vue devs and [get exclusive tips and insights](michaelnthiessen.com/newsletter) like these delivered straight to your inbox, every week.

> You have great content in your emails. I seriously learn something from every one of them. — Titus Decali

> Thanks for another beautiful tip 🙏 — Victor Onuoha

> Loving these, and the spaced repetition — Mark Goldstein

[Sign up here](michaelnthiessen.com/newsletter)