Read this on my blog Hey there, The stable release of Nuxt 4 is coming soon, and I'm busy getting Mastering Nuxt ready for it! Alex and I talked with Daniel Roe, the head of the Nuxt team, about the upcoming release of Nuxt 4. You can catch that Deja Vue episode below. With Mastering Nuxt we now have nine chapters of videos, with three more on the way. And all of it is updated and ready to work with Nuxt 4. Right now you can still get it with the early access discount, but once it's finished it will go up to full price. I wrote more about how that will work here: Master Nuxt 4 From Day One: No Waiting, No Outdated Content I also wrote an article based on a really fun lesson from the course where we use AI to generate the chat titles with a cool animation: Automatically Generate AI Chat Titles with Animation in Nuxt And as always, I've got some other tips and articles for you! — 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 → 🔥 Destructuring in a v-for Did you know that you can destructure in a v-for ? <li v-for="{ name, id } in users" :key="id" > </li>
It's more widely known that you can grab the index out of the v-for by using a tuple like this: <li v-for="(movie, index) in [ 'Lion King', 'Frozen', 'The Princess Bride' ]"> - </li>
When using an object you can also grab the key: <li v-for="(value, key) in { name: 'Lion King', released: 2019, director: 'Jon Favreau', }"> : </li>
It's also possible to combine these two methods, grabbing the key as well as the index of the property: <li v-for="(value, key, index) in { name: 'Lion King', released: 2019, director: 'Jon Favreau', }"> #. : </li>
🔥 Watching Nested Values You may not have known this, but you can easily watch nested values directly when using the Options API, just by using quotes: watch: { '$route.query.id'() { // ... } }
This is really useful for working with deeply nested objects! We can also watch nested values using the Composition API: watch( () => value.that.is.really.nested, () => { // ... } );
🔥 Nuxt Layout Fallback If you're dealing with a complex web app in Nuxt, you may want to change what the default layout is: <NuxtLayout fallback="differentDefault"> <NuxtPage /> </NuxtLayout>
Normally, the NuxtLayout component will use the default layout if no other layout is specified — either through definePageMeta , setPageLayout , or directly on the NuxtLayout component itself. This is great for large apps where you can provide a different default layout for each part of your app. 🎙️ #059 — Double Trouble: The Nuxt Surprise (with Daniel Roe) Big news in the Nuxt ecosystem. While you out there already know what has been announced - some of us didn't. Luckily, Daniel Roe, Head of the Nuxt team joins this DejaVue episode and discusses the highly anticipated "double trouble": Not one, but two major versions for Nuxt are on the horizon. After over a year of delays, Daniel reveals the strategic decision to release Nuxt 4 in less than a month from now, followed by Nuxt 5 which will include the long-awaited Nitro 3 integration and significant Vite improvements. The episode covers the smooth migration experience early adopters reported already, the philosophy behind careful breaking changes, and how the team plans to maintain a yearly major release cycle moving forward. Enjoy the Episode! Watch on YouTube or listen on your favorite podcast platform. Chapters: In case you missed them: 📜 Nuxt: Pages vs. Layouts vs. Components Nuxt comes with 3 different ways to organize your components: pages, layouts, and components. It can be difficult to know which to use when, so I wrote this article to help explain the differences. Check it out here: Nuxt: Pages vs. Layouts vs. Components 📜 Optimizing a Vue App Michelle does an excellent job of giving a high-level overview of best practices to keep your app speedy. Great as a starting off point or checklist for anyone looking to optimize their Vue app. Check it out here: Optimizing a Vue App 💬 Comments "Good code is its own best documentation. As you're about to add a comment, ask yourself, 'How can I improve the code so that this comment isn't needed?'" — Steve McConnell 🧠 Spaced-repetition: Configurable 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. We can make our composables more reusable by passing in an object that contains all of the configuration options for how we want the composable to behave: const state = ref({ email: '' }); const { history, undo, redo } = useRefHistory(state, { // Track history recursively deep: true, // Limit how many changes we save capacity: 10, });
We use an object here instead of a long list of parameters: const { history, undo, redo } = useRefHistory(state, true, 10));
Using an options object instead of parameters gives us several benefits. First, it's self-documenting. We have the name of the parameter right beside the value, so we never forget what each value is doing. We can also create a type for the entire options object: export type RefHistoryOptions { deep?: boolean; capacity?: number; }; export type RefHistoryReturn { history: Ref; undo: () => void; redo: () => void; }; export function useRefHistory( ref: Ref, options: RefHistoryOptions ): RefHistoryReturn {};
Second, we don't need to worry about ordering or unused options. The more potential edge cases we cover with a composable, the more options we'll have. But we usually only need to worry about a couple of them at one time — they're all optional. Third, it's much easier to add new options. Because the order doesn't matter and none of the options are required, adding a new capability to our composable won't break anything. We simply add it to the list of possible options and carry on. The pattern doesn't require a lot of work to implement, either: export function useRefHistory(ref, options) { const { deep = false, capacity = Infinity, } = options; // ... };
First, we pass in the options object as the last parameter. This makes it possible to have the options object itself as an optional parameter. The required params come first. Typically, there will only be one or two. More parameters is a code smell, and likely means that your composable is trying to do too much. The required parameter (or parameters) is very often a Ref , or a MaybeRef if we're also implementing the Flexible Arguments Pattern. We then access the options by destructuring. Doing this gives us a really clean and readable way of providing defaults. Remember, these are options so they should all have defaults. If the values are required they should likely have This helps to clarify what options are being used in this composable. It's not uncommon for one composable to use another composable, and in that case some of the options are simply passed along to the inner composable: export function useRefHistory(ref, options) { const { deep = false, capacity = Infinity, ...otherOptions, } = options; // Pass along some options we're not using directly useSomeOtherComposable(otherOptions); };
🔗 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: |
评论
发表评论