🔥 (#30) Reusability Fundamentals: The Configuration Pattern

Hey there,

I'm still trying to adjust to the darkness this time of year in Canada.

It's dark when I start work at 8, and dark again when I finish around 5. I work in my basement, so I don't get a lot of light during the day either.

So I'm trying to take some time during the day to get outside and get some sunlight (and fresh air).

Do you change your working habits throughout the year? A different schedule during winter or summer?

— Michael

🔥 How I deal with dynamic classes

A pattern I use constantly is triggering classes with boolean flags:

<template>
<div :class="disabled && 'disabled-component'">
Sometimes this component is disabled. Other times it isn't.
</div>
</template>
/* Some styles */
.disabled-component {
background-color: gray;
color: darkgray;
cursor: not-allowed;
}

Either the trigger is a prop I use directly, or a computed prop that tests for a specific condition:

disabled() {
return this.isDisabled || this.isLoading;
}

If I just need one class on an element, I use the logical AND to trigger it:

<div :class="disabled && 'disabled-component'"></div>

Sometimes it's a decision between two classes, so I'll use a ternary:

<div
:class="disabled ? 'disabled-component' : 'not-yet-disabled'"
/>

I don't often use more than two classes like this, but that's where an Object or Array comes in handy:

<div
:class="{
primary: isPrimary,
secondary: isSecondary,
tertiary: isTertiary,
}"
/>
<div
:class="[
isPrimary && 'primary',
isSecondary && 'secondary',
isTertiary && 'tertiary',
]"
/>

Of course, when it gets complex enough it's better to just have a computed prop that returns a string of class names (or returns an Object or Array):

<div :class="computedClasses" />

🔥 Reusability Fundamentals: The Configuration Pattern

So you've got an awesome CodeBlock component that does syntax highlighting, and even shows line numbers:

<CodeBlock language="js">
const myMessage = 'Highlighting code is supa ez';
</CodeBlock>

But now you need to support a second color theme.

Instead of copy and pasting (which is sometimes the right solution!), we can use props to help us create variations:

<!-- Uhhh, maybe not the best solution -->
<DarkModeCodeBlock language="js">
const myMessage = 'Highlighting code is supa ez';
</DarkModeCodeBlock>
<!-- This is what props were meant for -->
<CodeBlock
language="js"
theme="darkMode"
>
const myMessage = 'Highlighting code is supa ez';
</CodeBlock>

You already do this intuitively, so this may not be a huge revelation.

But the Configuration pattern is a fundamental pattern — you can't ignore it if you want to master reusability.

Dealing with prop explosions and understanding the Base Component Pattern are also part of mastering Configuration, the second level of reusability.

And the other, more interesting levels of reusability?

Well, mastering Configuration is vital to unlocking them. All the other levels build on top of this one.

đź“ś Using Vue for a VS Code extension?

This is a very interesting article on creating your own VS Code extension...

But you get to build the UI using Vue.

It goes into all the steps necessary to set up and get your extension running. From there, the sky is the limit (unless you're building rockets 🚀).

Read it now: Building a VS Code Extension Using Vue.js

đź—ž Nuxt 3! Yeah, it's here!

It was officially released yesterday, and comes with some amazing stuff:

  • Vue 3
  • Vite
  • Typescript
  • and so many other features

Check it out here.

Also, don't forget that Vue.js London is happening next week!

đź’¬ Repeated failure

As a rule, software systems do not work well until they have been used, and have failed repeatedly, in real applications. — Dave Parnas

I think Dave is talking about edge cases.

You think you've covered them all, but you never have. Not until real users start using it for real.

🧠 Spaced-repetition: Reducing Objects

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.

The reduce function is really great for converting arrays into objects, but it can be intimidating.

If we have a bunch of items that all have an id:

{
id,
//...
}

We can reorganize the array into an object, where the key for each item is the item's id:

const obj = arr.reduce((prev, next) => {
// Grab the id from the item
const { id } = next;
// Add the item to our object
prev[id] = next;
// Return the object so we can add more items
return prev;
}, {});

You get an object that looks like this:

{
'id1': { id: 'id1', ... },
'id2': { id: 'id2', ... },
'id3': { id: 'id3', ... },
}

If you want to group all objects in an array by a specific property, you can do something very similar:

const obj = arr.reduce((prev, next) => {
// Grab the property from the item that we want to group by
const { prop } = next;
// Add a new array to the object if this is the first one
// with this value
if (prev[prop] === undefined) {
prev[prop] = [];
}
// Add our item to this array
prev[prop].push(next);
// Return the object so we can add more items
return prev;
}, {});

Our final object looks like this:

{
'prop1': [
{ prop: 'prop1', ... },
{ prop: 'prop1', ... },
{ prop: 'prop1', ... },
],
'prop2': [
{ prop: 'prop2', ... },
{ prop: 'prop2', ... },
{ prop: 'prop2', ... },
],
}



p.s. I also have two courses: Reusable Components and Clean Components