Join 11,067 other Vue devs and get exclusive tips and insights delivered straight to your inbox, every week.
👋Hey friend! I work hard to send you amazing stuff each week.
— Michael
Hey!
Yesterday I gave my talk on Nuxt Layers at VueConf Toronto, and I think it went really well — maybe one of my best talks yet.
Alex and I are also doing some recording at the conference, so you'll see that in an upcoming episode soon.
I've also got a quick Black Friday reminder:
On Monday, November 25, you'll get a single email about my Black Friday sale. That's it.
As always, I've got some great tips and articles for you.
— Michael
With the Composition API we get fantastic TypeScript support, so this is quite straightforward:
defineProps<{src: string;style: 'square' | 'rounded';}>();
Doing this in the Options API is more complicated, and not as powerful as TypeScript.
Using the validator
option in a prop definition you can restrict a prop to a specific set of values:
export default {name: 'Image',props: {src: {type: String,},style: {type: String,validator: s => ['square', 'rounded'].includes(s)}}};
This validator function takes in a prop and returns either true
or false
— if the prop is valid or not.
I often restrict props like this when I need more options than a boolean
will allow but still want to restrict what can be set.
Button types or alert types (info, success, danger, warning) are some of the most common uses — at least in what I work on. Colours, too, are a really great use case for this.
When writing unit tests, you have access to a bunch of helper methods.
One super useful one is mountSuspended
. It lets you mount any component inside your Nuxt context with async setup:
import { describe, it, expect } from 'vitest';import { mountSuspended } from '@nuxt/test-utils/runtime';import MyComponent from './MyComponent.vue';describe('MyComponent', () => {it('renders the message correctly', async () => {const wrapper = await mountSuspended(MyComponent);expect(wrapper.text()).toContain('This component is set up.');});});
You’re also able to mount your app at a specific route, by passing in the App component and a route:
import { describe, it, expect } from 'vitest';import { mountSuspended } from '@nuxt/test-utils/runtime';import App from './App.vue';describe('About', () => {it('renders the about page', async () => {const wrapper = await mountSuspended(App, { route: '/about' });expect(wrapper.text()).toContain('Hi, my name is Michael!');});});
An extremely common question I get asked all the time is, “how do you know when to split up a component?”
I want to share a simple pattern with you that is basically fool-proof, and can be applied to lots of components with almost no thought.
When we encounter a v-if
(or v-show
) in our template, there's one main pattern we can use:
Extracting the body of each branch into its own component.
This is just one of many patterns included in Clean Components. There, we go into much more detail, examining each pattern more closely and really fine-tuning our understanding.
When we extract each branch body we go from this:
<div v-if="condition"><div><!-- Lots of code here --></div></div><div v-else><div><!-- Lots of other code --></div></div>
To this:
<div v-if="condition"><NewComponent /></div><div v-else><OtherComponent /></div>
We know we can do this for two reasons:
We know that each branch is semantically related, meaning all of that code works together to perform the same task.
Each branch also does distinct work — otherwise, why have a v-if
at all?
This means it's a perfect opportunity to create new components.
And by replacing a large chunk of code with a well-named component that represents the code’s intent, we make our code much more self-documenting. But we’ll get to that later on.
Data fetching is a crucial part of any web application. In this episode of DejaVue, we discuss the different ways to fetch data in Vue.js and Nuxt.js, and how to cache it.
We also talk about the experimental Suspense feature in Vue.js and how it can be used to improve the user experience, as well as how to handle third-party scripts in your application.
In addition, Nuxt's data fetching options are discussed, including the $fetch method, useFetch, useAsyncData and the useNuxtData composable. Finally, we cover server-side caching in Nuxt.js, including route rules, defineCachedEventHandler, and defineCachedFunction.
Enjoy the episode!
Watch on YouTube or listen on your favorite podcast platform.
Chapters:
In case you missed them:
There are a lot of different ways to redirect users in Nuxt, each with their own use cases.
In this (very detailed!) article I explore the different ways to redirect users in Nuxt, giving examples of when each might be useful.
Check it out here: How to Redirect in Nuxt (Every Single Way)
I recently spent some time updating the landing page for Clean Components Toolkit so that it will automatically update the outline as I update the course content itself.
In this article, I'll show you how it's done.
Check it out here: Dynamically Updating my Landing Page with Nuxt Content
Here are some upcoming events you might be interested in. Let me know if I've missed any!
The biggest Vue conference in the world! A two-day event with workshops, speakers from around the world, and socializing.
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." — Martin Fowler
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.
If you need to force a reload your entire page using Vue, all you need is some Javascript:
window.location.reload();
But this is a code smell — you should almost never need to use this method.
Instead, a better solution might be one of these:
onMounted
hooks or the top-level of setup
. You can also create an initialize
action for Pinia.key
attribute on a specific component, you can force just one component to reload instead of your entire app. Still a bit of a hack, but it gets the job done.Michael Hoffman curates a fantastic weekly newsletter with the best Vue and Nuxt links.
_p.s. I also have a bunch of products/courses: