🔥 (#178) Reactive CSS and Context-Aware Components

Hey all!

This week is a slow one for me after last week's launch.

I'm taking some time to do some refactoring, plan out my next projects, and enjoy August.

Enjoy the tips!

— Michael

🔥 Reactive CSS

In Vue 3 we can use reactive values in our script block just like we can in the template block.

<style scoped>    .button {      color: v-bind(buttonColor);    }  </style>

Behind the scenes, Vue uses CSS computed properties (aka CSS variables) scoped to each component.

The CSS remains static, but we can dynamically update the CSS variables whenever the reactive value changes.

More info can be found in the docs.

🔥 Creating Magic with Context-Aware Components

Context-aware components are "magical" — they adapt to what's going on around them automatically, handling edge cases, state sharing, and more.

There are 3 main types of context-aware components, but configuration is the one I find most interesting.

1. State Sharing

When you break up a large component into smaller ones, they often still need to share state.

Instead of pushing that work on whoever's consuming the components, you can make this happen "behind the scenes."

To give you more flexibility, you may break up a Dropdown component into Select and Option components. But to make it easier to use, the Select and Option components share the selected state with each other:

<!-- Used as a single component for simplicity -->  <Dropdown v-model="selected" :options="[]" />  <!-- Split up for more flexibility -->  <Select v-model="selected">    <Option value="mustard">Mustard</Option>    <Option value="ketchup">Ketchup</Option>    <div class="relish-wrapper">      <Option value="relish">Relish</Option>    </div>  </Select>

2. Configuration

Sometimes component behaviour needs to change based on what's going on in the rest of the application. This is often done to automagically handle edge cases that would otherwise be annoying to deal with.

A Popup or Tooltip should reposition itself so it doesn't overflow out of the page. But if that component is inside a modal, it should move, so it doesn't overflow out of the modal.

This can be done automagically if the Tooltip knows when it's inside a modal.

3. Styling

You already create context-aware CSS, applying different styles based on what's happening in parent or sibling elements.

.statistic {    color: black;    font-size: 24px;    font-weight: bold;  }  /* Give some separation between stats     that are right beside each other */  .statistic + .statistic {    margin-left: 10px;  }

CSS variables let us push this further, allowing us to set different values in different parts of the page.

🔥 Optimize for Humans

The most important thing we can do when writing code is to make it work.

The second most important thing is to make it understandable to other humans — including ourselves.

All too often we write clever code, terse code, code that isn't even understandable to ourselves when we come back to it a week or a month later.

Here are some ways to fix that:

  • Extract Components — by replacing a chunk of code with a meaningful name, we can separate the intention of the code from the implementation of the code. Good names are the most valuable form of abstraction that we have.
  • Shorter components — longer components are harder to understand at a glance, and that should be the ideal we strive for. The harder it is to understand a single component, the more mistakes you'll make, and the longer it will take for you implement anything new.
  • Optimize for the most tired, frustrated version of yourself — Remember that we all have bad days, and we want to productive every day, not just our best days. Write code that even the worst version of you can understand.

🎙️ #020 — Documentation and Migration: From Vue 2 to Vue 3 (with Natalia Tepluhina)

In this special in-person episode, Alex sits down with Natalia Tepluhina, a Principal Engineer and Vue.js Core Team Member, to discuss key topics such as documentation and the migration process from Vue 2 to Vue 3. Natalia shares her journey in the Vue community, insights on GitLab's migration experience, and tips for improving documentation.

Watch on YouTube or listen on your favorite podcast platform.

Chapters:

In case you missed them:

📜 Nuxt 3 State Management: Pinia vs useState

In Nuxt 3 we get a new useState composable.

But how does it compare to Pinia?

In this article for Vue Mastery, I discuss the main differences and when to use each.

Check it out here: Nuxt 3 State Management: Pinia vs useState

📜 Vue Project Directory Structure

Marco, a subscriber, once 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.

Check it out here: Vue Project Directory Structure

📅 Upcoming Events

Here are some upcoming events you might be interested in. Let me know if I've missed any!

PragVue 2024 — (September 17, 2024)

The first Czech Vue.js conference, taking place in Cinema City - Nový Smíchov

Check it out here

Vuejs.de Conf — (October 8, 2024 to October 9, 2024)

A community-driven Vue conference in Germany. Listen to great talks from great speakers and meet the wonderful VueJS Community.

Check it out here

Vue Fes Japan 2024 — (October 19, 2024)

Check it out here

VueConf Toronto 2024 — (November 18, 2024 to November 20, 2024)

My favourite Vue conference, in my own backyard! A three-day event with workshops, speakers from around the world, and socializing.

Check it out here

💬 Solve the Problem

"First, solve the problem. Then, write the code." — John Johnson

🧠 Spaced-repetition: Render Functions and Custom Component Options

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.

Vue's render functions and custom component options offer a powerful way to dynamically generate and control the rendering of components.

For instance, you can conditionally render child components or slots based on certain criteria.

Here's a basic render function that conditionally renders slots:

return () => {    const slots = useSlots();    const children = [];    if (props.val && slots.true) {      children.push(slots.true());    } else if (!props.val && slots.false) {      children.push(slots.false());    }    return children;  };

Custom component options can be used to tag components with specific properties that can be checked during rendering. This is useful when you have a set of components and you want to treat some of them differently based on their role or type.

For example, you can define a custom option in a child component:

export default {    props: ['if'],    conditional: true, // Custom component option    setup(props) {      // ...    },  };

And then in the parent component's render function, you can filter child components based on this custom option:

const slots = useSlots();  const conditionalComponents = slots    .default()    .filter((el) => el.type.conditional);  const children = [conditionalComponents];

This pattern is particularly useful when creating compound components that need to communicate and share state in a tightly coupled manner. It allows for a clean and declarative approach to rendering while maintaining flexibility and control over the component tree.

🔗 Want more Vue and Nuxt links?

Michael Hoffman curates a fantastic weekly newsletter with the best Vue and Nuxt links.

Sign up for it here.



p.s. I also have four products/courses: Clean Components Toolkit, Vue Tips Collection 2, Mastering Nuxt 3, and Reusable Components

Unsubscribe

评论

此博客中的热门博文

Scripting News: Tuesday, June 11, 2024

Scripting News: Tuesday, February 13, 2024