Exclusive tips every week

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.

    Picture of Michael Thiessen

    👋Hey friend! I work hard to send you amazing stuff each week.

    — Michael

    I really love and enjoy reading these emails.

    You are one of the most pro VueJS devs I know, and I am happy that you share this knowledge.

    Fabian Beer

    Here's my latest newsletter

    🔥 (225) Start with the Interface, Flexible Arguments, and Shorthand for Named Slots

    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

    🔥 Start with the Interface

    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:

    1. What arguments should the composable receive?
    2. What options do we want to include?
    3. What does the composable return?
    4. Do we want to use dynamic return values here?
    5. What does the minimum useful version look like, and how quickly can we get there?
    6. What does the final version look like? Is there anything easy we can do now to prepare for that?

    Of course, your composable will change and evolve over time.

    But it’s much easier to start off heading in the right direction.

    🔥 Flexible Arguments

    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 already
    const titleRef = ref('This is the title of the page');
    useTitle(titleRef);
    // We just have the string
    const 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.

    🔥 Shorthand for named slots

    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.

    📜 Make Your Components Easier to Think About

    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

    📜 Exploring Server Components in Nuxt

    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

    💬 Programmers and designers

    "If you make a general statement, a programmer says, 'Yes, but...'while a designer says, 'Yes, and...'." — André Bensoussan

    🧠 Spaced-repetition: How to Watch Props for Changes

    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)
    );

    Script Setup + Composition API

    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.

    Composition API + Options API

    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));
    },
    };

    Options API

    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.

    Sign up for it here.

    p.s. I also have a bunch of products/courses:

    Here's what others are saying

    I'm starting to think that your newsletter is one of the best things that happened to me this year. I just love these emails.
    Stanislaw Gregor
    I'm somewhere in the upper-middle level at Vue, and I never miss an email you and always find something cool when reading!
    Eduard Climov
    This is the first time where I'm actually enjoying email newsletters. I like your format a lot.
    Fahmi Alfituri
    You have great content in your emails. I seriously learn something from every one of them.
    Titus Decali
    Just wanted to say I enjoy these emails. They encourage me to constantly improve my craft. Fantastic work.
    Joe Radman
    Thanks for another beautiful tip 🙏
    Victor Martins Onuoha
    Loving these, and the spaced repetition.
    Mark Goldstein
    I really enjoy reading your emails, because I love Vue. Thanks for these emails.
    Arturo Espinoza
    I really love and enjoy reading these emails. You are one of the most pro VueJS devs I know, and I am happy that you share this knowledge.
    Fabian Beer
    THANK YOU! I did not know about the deep property, so I assumed you simply couldn't watch objects.
    Darryl Noakes
    I really must say you are doing a really great job. Now I am aware of a cleaner and more performant way to use Tailwind. Thanks a lot!
    Henry Eze
    Thank you so much, I really enjoy and appreciate your emails.
    Carlos Gonzalez
    Thanks for sharing great Vue tips.
    Fernando Navarro
    I really enjoy these tips.
    Martin H
    Thank you so much for the weekly Vue education. Thanks and live on longer to educate us more.
    Kabolobari Benakole
    I look forward to your emails every week. This week was something I knew, but I like to be reminded of. Thanks for keeping it up!
    Nathan Strutz
    Thank you for your weekly emails. I always look forward to learning a new tip about Vue or at least relearning old tips :)
    Colin Johnson
    I have really been enjoying your weekly emails, and I also got my two team members to join in on the fun as well.
    Keith Dawson
    Thank you for your newsletter, your explanations have very concise examples and I like it.
    Nicolas Decayeux
    Thanks A LOT for your great work!!! One of the few newsletters that I let pass!
    Martin Tillmann

    Want to level up your Vue skills?

    With over two million reads and 11,067 subscribers, you've come to the right place.

    Subscribe now to get exclusive insights and tips every week.