Hey there,
If you missed it, last week I released a free mini-course on building Vue 3 based Reactivity from Scratch, and already over 1000 people signed up!
But I have some more exciting news this week.
If you write tests, I've got an advanced workshop series coming up!
I've spent the last 6+ weeks doing customer interviews, in-depth research, and putting together this workshop. In it, you'll learn how to:
and more!
It's actually 3 workshops bundled together, so you get really good value for your money.
Find more details here, and please email me if you have any questions about it!
Have a great week!
— Michael
Let's say we're building an If
component and we want to use it in two main ways — with a default slot, or with two named slots.
Just the default slot:
<If :val="putConditionHere">Renders only if it's true</If>
Or using the named slots to access both branches:
<If :val="putConditionHere"><template #true>Renders only if it's true</template><template #false>Renders only if the condition is false</template></If>
This is how we'd have to arrange the slots in order to make this work:
<template><slot v-if="val" /><template v-if="!$slots.default"><slot v-if="val" name="true" /><slot v-if="!val" name="false" /></template></template>
You’ll notice we use a template
to group the named slots. We’re also checking $slots
to see if we’ve put anything in the default slot or not.
We need to do this, otherwise we’ll render the default
and true
slots whenever our condition is true, which isn’t what we want! We want these to be mutually exclusive — you can either use the default slot or the named true
slot.
Now, we can use it in either way.
Just the default slot to access the true branch, or using two named slots to access both the true and false branches.
When you register a component globally, you can use it in any template without importing it a second time:
// Vue 3import { createApp } from 'vue';import GlobalComponent from './GlobalComponent.vue';const app = createApp({})app.component('GlobalComponent', GlobalComponent);
In Vue 2 you can register global components like this:
// Vue 2import Vue from 'vue';import GlobalComponent from './GlobalComponent.vue';Vue.component('GlobalComponent', GlobalComponent);
Now you can use GlobalComponent
in your templates without any extra work!
Of course, globally registered components have the same pros and cons as global variables. So use this sparingly.
Props are helpful, but they have two glaring issues:
*not technically impossible, but not something you want to do.
The solution to these two problems is the same, but we'll get there in a second.
Many components you create are contentless components. They provide a container, and you have to supply the content. Think of a button, a menu, an accordion, or a card component:
<Card title="Shrimp Tempura"><img src="picOfShrimp.jpg" /><div><p>Here are some words about tempura.</p><p>How can you go wrong with fried food?</p></div><a href="www.michaelnthiessen.com/shrimp-tempura">Read more about Shrimp Tempura</a></Card>
You can often pass this content in as a regular String
. But many times, you want to pass in a whole chunk of HTML, maybe even a component or two.
You can't do that with props.*
*again, yes, you could do this, but you'll definitely regret it.
Props also require that you plan for all future use cases of the component. If your Button
component only allows two values for type
, you can't just use a third without modifying the Button
:
<!-- You just have to *believe* it will work --><Button type="AWESOME" />
The component doesn't allow for that...
<!-- Button.vue --><script setup>defineProps<{type: 'Primary' | 'Secondary' // AWESOME is not an option here}>();</script>
I'm not a psychic, and I'm guessing you aren't either.
The solution to these problems?
I think I gave it away with my card example above...
...slots!
Slots allow you to pass in whatever markup and components you want, and they also are relatively open-ended, giving you lots of flexibility. This is why in many cases, slots are simply better than props.
In this episode, Alex is joined by fellow Nuxt core team member Lucie Haberer, who is not only a DX Engineer at Prismic, doing open source but also public speaking.
Together they talk about Lucie's recent free Nuxt and Nuxt UI course and how she got into Vue and Nuxt. Lucie explains further why she fell in love with Nuxt modules and which modules she built so far - with some enlightening surprise there!
In addition, they talk about how Open Source works at Prismic - from when they do open source over to sponsoring projects and contributing - and many more insights.Â
Enjoy the episode!
Watch on YouTube or listen on your favorite podcast platform.
Chapters:
In case you missed them:
Nuxt 3 provides powerful configuration options, allowing you to adapt your application to different use cases.
The two key parts of Nuxt 3's configuration system are runtimeConfig and appConfig.
This article will explain the purpose and differences between these two options and show you how to use them.
Check it out here: Configuration in Nuxt 3: runtimeConfig vs. appConfig
This is a high-level overview of 12 of the most crucial features in Nuxt 3.
I explain why each is important, and how Nuxt 3 works hard to make your dev experience as effortless as possible.
Check it out here: The 12 Best Features in Nuxt 3
Here are some upcoming events you might be interested in. Let me know if I've missed any!
A community-driven Vue conference in Germany. Listen to great talks from great speakers and meet the wonderful VueJS Community.
My favourite Vue conference, in my own backyard! A three-day event with workshops, speakers from around the world, and socializing.
The biggest Vue conference in the world! A two-day event with workshops, speakers from around the world, and socializing.
"Telling a programmer there's already a library to do X is like telling a songwriter there's already a song about love." — Pete Cordell
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.
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.
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>
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.
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 statsthat 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.
Michael Hoffman curates a fantastic weekly newsletter with the best Vue and Nuxt links.
p.s. I also have four products/courses: Clean Components Toolkit, Vue Tips Collection 2, Mastering Nuxt 3, and Reusable Components