Read this on my blog Hey everyone, Last week, Nuxt Image v2 was released. The main story here is much better TypeScript support, but of course, there are lots of other improvements! You can read the announcement here. And if you missed it, Nuxt 4.2 was also released just a few weeks ago. That announcement is here. Have a great week! — Michael Nuxt Tips Collection Master Nuxt without hours digging through docs. Learn what you need in just 5 minutes a day: - 117 practical tips to unlock hidden features of Nuxt
- 14 chapters covering components, routing, SSR, testing and more
- 3 daily tips for 3 months via email
- 7 real-world code repos to learn from
- Reviewed by Nuxt core team for accuracy
"Highly recommend Michael's Nuxt Tips Collection. He's one of the best Vue & Nuxt teachers I know." — Sébastien Chopin Master Nuxt Today → 🔥 Extract Conditional Pattern An extremely common question I get asked all the time is, "how do you know when to split up a component?" I want to share a simple pattern with you that is basically fool-proof, and can be applied to lots of components with almost no thought. When we encounter a v-if (or v-show) in our template, there's one main pattern we can use: Extracting the body of each branch into its own component. This is just one of many patterns included in Clean Components. There, we go into much more detail, examining each pattern more closely and really fine-tuning our understanding. When we extract each branch body we go from this: <div v-if="condition"> <div> <!-- Lots of code here --> </div> </div> <div v-else> <div> <!-- Lots of other code --> </div> </div>
<div v-if="condition"> <NewComponent /> </div> <div v-else> <OtherComponent /> </div>
We know we can do this for two reasons: - Each branch is semantically related
- Each branch does distinct work
We know that each branch is semantically related, meaning all of that code works together to perform the same task. Each branch also does distinct work — otherwise, why have a v-if at all? This means it's a perfect opportunity to create new components. And by replacing a large chunk of code with a well-named component that represents the code's intent, we make our code much more self-documenting. But we'll get to that later on. 🔥 Component Metadata Not every bit of info you add to a component is state. For example, sometimes, you need to add metadata that gives other components more information. For example, if you're building a bunch of different widgets for an analytics dashboard like Google Analytics or Stripe. If you want the layout to know how many columns each widget should take up, you can add that directly on the component as metadata: <script setup> defineOptions({ columns: 3, }); </script>
Or if you're using the Options API: export default { name: 'LiveUsersWidget', // Just add it as an extra property columns: 3, props: { // ... }, data() { return { //... }; }, };
You'll find this metadata as a property on the component: import LiveUsersWidget from './LiveUsersWidget.vue'; const { columns } = LiveUsersWidget;
With the Composition API we can't access this value directly, because there's no concept of a "current instance". Instead, we can make our value a constant: <script setup> const columns = 3; defineOptions({ columns, }); </script>
But this value cannot change, because defineOptions is a compiler macro and the value is used at compile time. If you're using the Options API you can access the metadata from within the component through the special $options property: export default { name: 'LiveUsersWidget', columns: 3, created() { // `$options` contains all the metadata for a component console.log(`Using ${this.$options.columns} columns`); }, };
Just keep in mind that this metadata is the same for each component instance and is not reactive. Other uses for this include (but are not limited to): - Keeping version numbers for individual components
- Custom flags for build tools to treat components differently
- Adding custom features to components beyond computed props, data, watchers, etc.
- and many more I can't think of!
I used this technique to build my Totally Unnecessary If/Else Component if you want to see it in action. 🔥 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: - What arguments should the composable receive?
- What options do we want to include?
- What does the composable return?
- Do we want to use dynamic return values here?
- What does the minimum useful version look like, and how quickly can we get there?
- 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. 📜 Mastering Prose Components in Nuxt Content Prose components are perhaps one of the best features of Nuxt Content! In this article, we'll go through a few examples of how you can easily create your own. Check it out here: Mastering Prose Components in Nuxt Content 📜 Better Navigation with NuxtLink The NuxtLink component may seem simple at first glance, but there's a lot going on beneath the surface. It's one of the easiest Nuxt components to use, while giving our apps a big performance boost. In this article we see some things about NuxtLink you may not have known. Check it out here: Better Navigation with NuxtLink 💬 Frustation "Give someone a program, you frustrate them for a day; teach them how to program, you frustrate them for a lifetime." — David Leinweber 🧠 Spaced-repetition: Hybrid API: Composition API + Options API 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 don't have to decide between Options API and Composition API, you can use both: export default { setup() { const darkMode = ref(false); return { darkMode } }, methods: { saveDarkMode() { localStorage.setItem('dark-mode', this.darkMode); }, } };
We can also update values from the Options API: export default { setup() { const darkMode = ref(false); return { darkMode } }, methods: { changeTheme(val) { this.darkMode = val; } } };
Although you can access Composition API from the Options API, it's a one-way street. The Composition API cannot access anything defined through the Options API: export default { setup() { const darkMode = ref(false); // We can't access the method this.changeTheme(true); return { darkMode } }, methods: { changeTheme(val) { this.darkMode = val; } }
This can be useful for incremental adoption of the Composition API, because it lets you use reusable composables in your Options API. But mixing two styles of writing components is likely to cause more headaches than it solves, so please think twice before doing this! 🔗 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: |
评论
发表评论