Exclusive tips every week

Join 11,067 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

    🔥 (#87) Nuxt Nation and Using useRoute

    Hey!

    Today I'm giving a talk at Nuxt Nation, it's a live preview of one of the lessons from Mastering Nuxt 3.

    It's totally free, totally online, so go watch it here: https://nuxtnation.com/

    Also, next week I'm doing a huge Black Friday sale on all of my courses! That includes:

    Don't buy them at full price this week!

    I also know that many of you are planning on taking advantage of lots of other fantastic sales, so this gives you a chance to plan out your spending better.

    Have a great week!

    — Michael

    🔥 Using useRoute

    The useRoute composable from Vue Router (and included in Nuxt 3) gives us easy access to the current route:

    const route = useRoute();

    In a template we have an injected variable instead:

    <template>
      <pre>{{ $route }}</pre>
    </template>

    This route object comes straight from Vue Router, so it contains everything you’d expect:

    • path
    • query
    • params
    • and more

    Here are the docs for the route object: https://router.vuejs.org/api/interfaces/RouteLocationNormalizedLoaded.html

    🔥 Forcing a Component to Update

    What do you do if a component isn’t updating the way it should?

    Likely, this is caused by a misunderstanding and misuse of the reactivity system.

    But let’s look at a quick solution using forceUpdate:

    import { getCurrentInstance } from 'vue';
    
    const methodThatForcesUpdate = () => {
      // ...
      const instance = getCurrentInstance();
      instance.proxy.forceUpdate();
      // ...
    };

    Using the Options API instead:

    export default {
      methods: {
        methodThatForcesUpdate() {
          // ...
          this.$forceUpdate();  // Notice we have to use a $ here
          // ...
        }
      }
    }

    Now, here comes the sledgehammer if the previous approach doesn’t work.

    I do not recommend using this approach. However, sometimes you just need to get your code to work so you can ship and move on.

    But please, if you do this, keep in mind this is almost always the wrong way, and you’re adding tech debt in to your project.

    We can update a componentKey in order to force Vue to destroy and re-render a component:

    <template>
      <MyComponent :key="componentKey" />
    </template>
    
    <script setup>
    import { ref } from 'vue';
    const componentKey = ref(0);
    
    const forceRerender = () => {
      componentKey.value += 1;
    };
    </script>

    The process is similar with the Options API:

    export default {
      data() {
        return {
          componentKey: 0,
        };
      },
      methods: {
        forceRerender() {
          this.componentKey += 1;
        }
      }
    }

    You can find a deeper explanation here: https://michaelnthiessen.com/force-re-render/

    I got lots of great talk suggestions in this thread!

    Now I just have to find the time to go through them.

    https://twitter.com/MichaelThiessen/status/1592487599465177088?s=20&t=SLhE9cjJu1ecTYYcy4hXDQ

    📜 Nuxt Extends (video)

    In this video from LearnVue, we see how powerful the extends feature is in Nuxt 3.

    Check it out here: Nuxt Extends (video)

    💬 First Do It

    "First do it, then do it right, then do it better." — Addy Osmani

    📅 Events

    November 16-17 — Nuxt Nation (TODAY!)

    This is an online (and entirely free!) event all about Nuxt!

    I'll be speaking, along with many amazing people from the Nuxt team and beyond. It's going to be great!

    Get your ticket here: https://nuxtnation.com/

    December 1-24 — Advent of Vue

    Get a fun, holiday-themed Vue challenge every day for 24 days!

    I'm contributing a few challenges to this, along with some other incredible people from the Vue community.

    Sign up for the challenges here: https://adventofvue.com/

    🧠 Spaced-repetition: Multiple v-models

    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.

    In Vue 3 we're not limited to a single v-model:

    <AddressForm
      v-model:street-name="streetName"
      v-model:street-number="streetNumber"
      v-model:postal-code="postalCode"
      v-model:province="province"
      v-model:country="country"
    />

    This makes dealing with complex forms a lot easier!

    First, we need to create the props and events for v-model to hook into (I've omitted a couple v-models for simplicity):

    <!-- AddressForm.vue -->
    <script setup>
    // Set up all the props
    defineProps({
      streetName: {
        type: String,
        required: true,
      },
      streetNumber: {
        type: Number,
        required: true,
      },
      // ...
      country: {
        type: String,
        required: true,
      },
    });
    
    // Set up our events
    defineEmits([
      'update:streetName',
      'update:streetNumber',
      // ...
      'update:country',
    ]);
    </script>

    Then, inside the component we use the prop to read the value, and emit update:<propname> to update it:

    <template>
      <form>
        <input
          type="text"
          :value="streetName"
          @input="$emit('update:streetName', $event.target.value)"
        >
        <input
          type="text"
          :value="streetNumber"
          @input="$emit('update:streetNumber', $event.target.value)"
        >
        <!-- ... -->
        <input
          type="text"
          :value="country"
          @input="$emit('update:country', $event.target.value)"
        >
      </form>
    </template>

    You can read more about using multiple v-models here.



    p.s. I also have three courses: Vue Tips Collection, Reusable Components and Clean Components

    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
    🎉 Get 30% off Vue Tips Collection!
    Get it now!