If you like Anthony's newsletter on Vue.js Developers, you'll enjoy this one, too.
Join 13,567+ 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
We just released the final videos of Mastering Nuxt: Full Stack Unleashed!
This last chapter covers authentication with Nuxt Auth Utils. We cover session management, protecting both server routes and client routes, seeding data when a user logs in, and more.
It's the best way to learn Nuxt, and is up-to-date with Nuxt 4. You can read more about what that means in this article:
Master Nuxt 4 from Day One: No Waiting, No Outdated Content
Since the course is now complete, the early access period will be ending soon. So grab your copy for a great price before the price goes up!
Mastering Nuxt: Full Stack Unleashed
— Michael
When writing a composable, don’t immediately dive into implementing it.
Instead, take a moment to figure out how you will be using the component. Take some time to think about the interface between the composable and the rest of your app.
A few minutes upfront can save you a lot of tears and frustration later on.
Here are a few questions you may want to ask yourself before starting:
Of course, your composable will change and evolve over time.
But it’s much easier to start off heading in the right direction.
Sometimes we have a ref
that we want to use with our composable. Sometimes we just have the raw data.
Wouldn’t it be nice if it didn’t matter what we already had? Then we could use our composables and it would just work?
Here’s an example using the useTitle
composable from VueUse:
// We have a ref alreadyconst titleRef = ref('This is the title of the page');useTitle(titleRef);// We just have the stringconst title = 'This is the title of the page';const titleRef = useTitle(title);
We can do this by implementing the Flexible Arguments pattern:
export function useTitle(maybeRef) {const titleRef = ref(maybeRef);// Use titleRef in the composable}
The ref
function will either create a ref
for us, or return a ref
if we give it one.
This means that we can pass it either type and we know we’ll get a ref back.
The opposite is true with the unref
function. If we need to use a raw primitive value rather than a ref
in our composable, we can use unref
to achieve a similar result.
export function useTitle(maybeRef) {const titleString = unref(maybeRef);// Use titleString in the composable}
If you want more patterns on writing better composables, check out my course: Composable Design Patterns.
Named slots also have a shorthand syntax, one that's much nicer to look at.
Instead of writing this:
<DataTable><template v-slot:header><TableHeader /></template></DataTable>
We can write this:
<DataTable><template #header><TableHeader /></template></DataTable>
Not a huge difference, but a little cleaner for sure. I think the #
character is easier to pick out than v-slot
when reading code.
I hate thinking.
Well, actually, I love thinking, but only when I’m able to solve problems or make progress with it.
But often our code gets in the way of this. And as one workshop attendee said about reading code, “if you’re confused, it’s not your fault.”
This article goes over some ways you can make your code easier to think about, so you’re less confused and can actually get stuff done.
Check it out here: Make Your Components Easier to Think About
You may have heard about server components, but there are some really interesting things you can do with them.
In this article I explore a few really cool things we can do with server components.
Check it out here: Exploring Server Components in Nuxt
"If you make a general statement, a programmer says, 'Yes, but...'while a designer says, 'Yes, and...'." — André Bensoussan
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.
With the Composition API, we have several great options for watching props.
The recommended approach would be using either watch
or watchEffect
in your script setup
:
import { watch, watchEffect } from "vue";const props = defineProps<{ count: number }>();watch(() => props.count,(val) => {console.log(val);});watchEffect(() => console.log(props.count));
When using the watch
method, we have to provide a getter function instead of passing the value directly. This is because the prop
object itself is reactive, but the individual props are not.
You can test this for yourself by passing in the reactive prop
object directly:
watch(props,(val) => {console.log(val);});
The difference between watch
and watchEffect
is that watch
requires us to specify exactly what we’re watching, while watchEffect
will simply watch every value that is used inside of the method that we pass to it.
So we have a tradeoff between simplicity and flexibility.
If you’re using the setup()
function within the Options API, the only difference is in how we specify the props. Otherwise, everything else works exactly the same:
import { watch, watchEffect } from "vue";export default {props: {count: {type: Number,required: true,},},setup(props) {watch(() => props.count,(val) => {console.log(val);});watchEffect(() => console.log(props.count));},};
The process is straightforward with the Options API.
Just use the name of the prop as the name of the watcher, and you’re good to go!
export default {props: {count: {type: Number,required: true,},},watch: {count(val) {console.log(val);},},};
Although this syntax is simpler than the Composition API syntax, the tradeoff is that there is far less flexibility.
If you want to watch multiple things at once, or have any fine-grained control over the dependencies, the Composition API is much easier to use.
Michael Hoffman curates a fantastic weekly newsletter with the best Vue and Nuxt links.
p.s. I also have a bunch of products/courses: