Exclusive tips every week

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

    🔥 (252) Optimize for Humans, Mock API Routes, and Accessing Parent Components

    Hey everyone,

    Getting back into the rhythm of things here in mid-January. Hope you're settling back into work after the holidays.

    Some tips and articles to help you ease back in.

    — Michael

    🔥 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.

    🔥 Easily Mock API Routes in Nuxt

    If you've ever written unit tests, you'll have needed to mock out API endpoints that are used in your components or stores.

    With @nuxt/test-utils this is really simple, because you get the registerEndpoint utility method:

    import { registerEndpoint } from '@nuxt/test-utils/runtime';
    import userTestData from './userTestData.json';
    registerEndpoint('/users/', () => userTestData);
    // ...tests

    You can mock any server route (API endpoint), including external endpoints if you need.

    🔥 Directly accessing parent components (and why)

    Props down, events up. That's how your components should communicate — most of the time.

    But in rare cases, that just doesn't work.

    If you need direct access to the parent component, you should just use provide/inject to pass down the relevant value or method:

    import { provide } from 'vue';
    const someMethodInTheParent = () => {};
    provide('method', someMethodInTheParent)

    Then, inject it into the child component:

    import { inject } from 'vue';
    const method = inject('method');
    method();

    In Vue 2, you can also use the instance property $parent:

    // Tight coupling like this is usually a bad idea
    this.$parent.methodOnParentComponent();

    This is simpler, but leads to higher coupling and will more easily break your application if you ever refactor.

    You can also get direct access to the application root, the very top-most component in the tree, by using $root. Vue 2 also has $children, but these were taken out for Vue 3 (please don't use this one).

    When would these be useful?

    There are a few different scenarios I can think of. Usually, when you want to abstract some behaviour and have it work "magically" behind the scenes.

    You don't want to use props and events to connect up a component in those cases. Instead, you use provide/inject, $parent, or $root, to automatically connect the components and make things happen.

    (This is similar to the Compound Component pattern)

    But it's hard to come up with an example where this is the best solution. Using provide/inject is almost always the better choice.

    📜 How to Use Error Handling to Create Rock-Solid Nuxt Apps

    Error handling is so important to building robust applications.

    In this article, we'll go over how to use error handling (all of it!) to create rock-solid Nuxt apps.

    Check it out here: How to Use Error Handling to Create Rock-Solid Nuxt Apps

    📜 How to access DOM elements with useTemplateRef

    Learn how to access DOM elements with the useTemplateRef composable.

    I went deep into the useTemplateRef composable, and how it compares to the old way of accessing DOM elements.

    I also share some best practices for using this composable!

    Check it out here: How to access DOM elements with useTemplateRef

    đź’¬ "Users"

    "There are only two industries that refer to their customers as 'users'." — Edward Tufte

    đź§  Spaced-repetition: Inline Composables

    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.

    You can define composables inline, keeping them in your SFC file:

    <script setup>
    const useCount = (i) => {
    const count = ref(0);
    const increment = () => count.value += 1;
    const decrement = () => count.value -= 1;
    return {
    id: i,
    count,
    increment,
    decrement,
    };
    };
    const listOfCounters = [];
    for (const i = 0; i < 10; i++) {
    listOfCounters.push(useCount(i));
    }
    </script>
    <template>
    <div v-for="counter in listOfCounters" :key="counter.id">
    <button @click="counter.decrement()">-</button>
    {{ counter.count }}
    <button @click="counter.increment()">+</button>
    </div>
    </template>

    But is there any point to doing this?

    If you’re keeping your components focused on a specific task (and you should be), then it stands to reason that the logic is also focused on a single task.

    This means that if you wrap up all relevant logic into an inline composable, you’ve wrapped up all — or nearly all — the logic that this component has:

    <script setup>
    // Create an inline composable
    const useStuff = () => {
    <all_our_logic>
    };
    // ...only to destructure most of it to use in our template
    const {
    value,
    anotherValue,
    eventHandler,
    anotherEventHandler
    } = useStuff();
    </script>

    At which point, we might as well write our logic without that unnecessary wrapper:

    <script setup>
    const value = ...
    const anotherValue = ...
    const eventHandler = ...
    const anotherEventHandler = ...
    </script>

    However, if you have do have logic that can be encapsulated nicely within this inline composable, it could make your code cleaner and easier to use.

    Using lexical scoping to create more boundaries within your files helps you to understand and think through your code, which is always helpful.

    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.