🔥 (229) Limitations of Props, Mocking API Routes, and more

​ ​

Read this on my blog

Hey there!

I just got back from vacation, and just wrapped up a few updates to Mastering Nuxt.

My main focus for August is the Advanced Reactivity course. It's going to be exercise based, with videos walking you through each problem and solution, so you'll get real hands on experience with advanced reactivity in Vue.

And when I say advanced, I mean advanced. Most of what we cover I had never used before, so I had to spend a lot of time tinkering and experimenting in order to understand these things for myself first.

Some topics that we'll be covering are:

  • Effect scopes
  • Flush modes with watchers
  • Custom refs
  • Strategies for debugging and tracking down reactivity bugs
  • When and how to opt out of reactivity

I'll be sharing more in the coming weeks. If you have any questions on this, let me know!

Enjoy your tips!

— Michael

Clean Components Toolkit

Are your Vue components getting messy and hard to maintain? Struggling with when to split components or how to organize your code?

The Clean Components Toolkit teaches you battle-tested patterns and principles to write cleaner, more maintainable Vue apps, including:

  • 3.5 + hours of focused video content plus comprehensive written materials
  • Step-by-step refactoring examples showing real-world applications
  • Interactive quizzes to reinforce your learning
  • 20 + practical tools and patterns for component organization
  • Lifetime access to updates and new content

You'll master:

  • Component splitting and combining — when (and when not) to break up components
  • State management across components — especially as complexity grows
  • Logic organization and reuse — using the three core component types
  • Seamless refactoring techniques — transform messy code into clean, maintainable components
"The Clean Components Toolkit's concise, to-the-point lessons made the learning process feel effortless and led to a deeper understanding of the subject matter." — Alex Rodriguez

Master Clean Components Now →

🔥 How to make a variable created outside of Vue reactive

If you get a variable from outside of Vue, it's nice to be able to make it reactive.

That way, you can use it in computed refs, watchers, and everywhere else, and it works just like any other state in Vue.

You can do this by using ref or reactive directly:

import { ref } from 'vue';    // Can be done entirely outside of a Vue component  const externalVariable = getValue();  const reactiveVariable = ref(externalVariable);    // Access using .value  console.log(reactiveVariable.value);

Using reactive instead:

import { reactive } from 'vue';    // Can be done entirely outside of a Vue component  const externalVariable = getValue();  // Reactive only works with objects and arrays  const anotherReactiveVariable = reactive(externalVariable);    // Access directly  console.log(anotherReactiveVariable);

If you're still on Vue 2 or using the Options API (as many are), you can use observable instead of reactive to achieve the same result.

Otherwise, to get this to work with all you need is to put it in the data section of your component:

const externalVariable = getValue();    export default {    data() {      return {        reactiveVariable: externalVariable,      };    }  };

🔥 The limitations of props

Props are helpful, but they have two glaring issues:

  • Impossible to pass markup*
  • Not that flexible

*not technically impossible, but not something you want to do.

The solution to these two problems is the same, but we'll get there in a second.

Many components you create are contentless components. They provide a container, and you have to supply the content. Think of a button, a menu, an accordion, or a card component:

<Card title="Shrimp Tempura">    <img src="picOfShrimp.jpg" />    <div>      <p>Here are some words about tempura.</p>      <p>How can you go wrong with fried food?</p>    </div>    <a href="www.michaelnthiessen.com/shrimp-tempura">      Read more about Shrimp Tempura    </a>  </Card>

You can often pass this content in as a regular String. But many times, you want to pass in a whole chunk of HTML, maybe even a component or two.

You can't do that with props.*

*again, yes, you could do this, but you'll definitely regret it.

Props also require that you plan for all future use cases of the component. If your Button component only allows two values for type, you can't just use a third without modifying the Button:

<!-- You just have to *believe* it will work -->  <Button type="AWESOME" />

The component doesn't allow for that...

<!-- Button.vue -->  <script setup>  defineProps<{    type: 'Primary' | 'Secondary' // AWESOME is not an option here  }>();  </script>

I'm not a psychic, and I'm guessing you aren't either.

The solution to these problems?

I think I gave it away with my card example above...

...slots!

Slots allow you to pass in whatever markup and components you want, and they also are relatively open-ended, giving you lots of flexibility. This is why in many cases, slots are simply better than props.

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

📜 What is Universal Rendering in Nuxt?

Modern web development has brought forth two main types of applications: Single Page Apps (SPA) and Server Side Rendered apps (SSR).

While each has its advantages, Nuxt offers a unique approach that combines the benefits of both types.

This article delves deeper into the workings of SPAs, SSRs, and the innovative Universal Rendering of Nuxt.

Check it out here: What is Universal Rendering in Nuxt?

📜 Prisma with Nuxt: Seeding the Database with Dummy Data (3 of 5)

A database is useless without any data.

But with Prisma, adding in seed data (or "dummy" data) is extremely easy.

In this article we'll cover:

  • How to generate our Prisma client
  • How to update our Supabase database with migrations
  • How to add in dummy data

Check it out here: Prisma with Nuxt: Seeding the Database with Dummy Data (3 of 5)

💬 Great Developers

"Every great developer you know got there by solving problems they were unqualified to solve until they actually did it." — Patrick McKenzie

🧠 Spaced-repetition: Reactivity and Callbacks

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.

Callback is a bit of a dirty word in Vue, but there are great use cases for them.

Consider a scenario where a parent component needs to react to changes in its children's state. You can use a reactive object provided by the parent and injected by the children to keep track of changes.

Here's an example:

// Parent component  const sharedState = reactive({});  provide('sharedState', sharedState);    // Child component  const sharedState = inject('sharedState');

When a child component updates a property of sharedState, Vue's reactivity system ensures that any effects or computed properties that depend on sharedState are automatically re-evaluated.

You can use callbacks to allow child components to register themselves with the parent or to signal the parent to perform an action.

Here's how you might implement a callback with provide and inject:

// Parent component  const registerChild = (child) => { /* ... */ };  provide('registerChild', registerChild);    // Child component  const registerChild = inject('registerChild');  registerChild(/* child details */);

This pattern is powerful for creating complex interactions between components while keeping the logic encapsulated and manageable.

It's especially useful in the Compound Components pattern.

🔗 Want more Vue and Nuxt links?

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:

Unsubscribe

评论

此博客中的热门博文

Scripting News: Tuesday, August 20, 2024

The magic of scoped slots in Vue ✨ (3/4)