Hey all! I've got two great new articles for you this week, and some news about the Deja Vue podcast. Should the Options API be deprecated? First, one on the Options API vs the Composition API. Last week on Twitter / X there was a lot of discussion going around on whether or not the Options API should be sunset in Vue 4. There were a lot of opinions, of course. So I spent some time (okay, a lot of time) researching and writing my own take on the issue. It's a long one, but I think it needs to be in order to tackle this topic properly. Composition API vs. Options API This weird thing in useAsyncData Second, I noticed that useAsyncData in Nuxt can be used both asynchronously and synchronously. Weird, right? So I had to dig into it to figure out how that actually works, and how we can use that in our own code. I wrote all about it on the Mastering Nuxt blog: Async and Sync? How useAsyncData does it all Q+A with Evan You on Deja Vue Alex and I will be having Evan You on soon, so we're gathering your questions for a Q+A section. So if you have anything you'd like to ask Evan about, just hit reply and we might get to it on podcast! And after you're done with the tips, don't forget to check out the latest episode of Deja Vue!. Oh, and I've switched to using vue-email for the newsletter, so hopefully the formatting is better for you! — Michael 🔥 How to Watch Props for Changes With the Composition API, we have several great options for watching props. The recommended approach would be using either watch or watchEffect in your script setup : import { watch, watchEffect } from "vue"; const props = defineProps<{ count: number }>(); watch( () => props.count, (val) => { console.log(val); } ); watchEffect( () => console.log(props.count) );
Script Setup + Composition API When using the watch method, we have to provide a getter function instead of passing the value directly. This is because the prop object itself is reactive, but the individual props are not. You can test this for yourself by passing in the reactive prop object directly: watch( props, (val) => { console.log(val); } );
The difference between watch and watchEffect is that watch requires us to specify exactly what we're watching, while watchEffect will simply watch every value that is used inside of the method that we pass to it. So we have a tradeoff between simplicity and flexibility. Composition API + Options API If you're using the setup() function within the Options API, the only difference is in how we specify the props. Otherwise, everything else works exactly the same: import { watch, watchEffect } from "vue"; export default { props: { count: { type: Number, required: true, }, }, setup(props) { watch( () => props.count, (val) => { console.log(val); } ); watchEffect(() => console.log(props.count)); }, };
Options API The process is straightforward with the Options API. Just use the name of the prop as the name of the watcher, and you're good to go! export default { props: { count: { type: Number, required: true, }, }, watch: { count(val) { console.log(val); }, }, };
Although this syntax is simpler than the Composition API syntax, the tradeoff is that there is far less flexibility. If you want to watch multiple things at once, or have any fine-grained control over the dependencies, the Composition API is much easier to use. 🔥 Shallow Refs You can optimize the reactivity in your app by using shallowRef : const user = shallowRef({ name: 'Michael', friends: [ { name: 'Travis', friends: [ // ... ], }, { name: 'Matthew', friends: [ // ... ], }, ] });
Reactivity is only triggered when the value of the ref itself is changed: // Triggers a reactive update user.value = matthew;
But modifying any of the nested properties won't trigger anything: // Nothing happens user.value.name = 'Martin';
Adding deep reactivity to a large object can cost you a lot of performance, so this can be useful for saving some CPU cycles. You can also manually trigger a reactive update if it's necessary: // Log the user whenever it changes watchEffect(() => console.log(user)); // Update nested state (no log happens) user.value.name = 'Martin'; // Force a reactive update to trigger triggerRef(user); // [user object]
Here are the docs for shallowRef and triggerRef. 🔥 How to watch anything in your component It took me a very long time to realize this, but anything in your component that is reactive can be watched. This includes computed refs as well: const first = ref('Michael'); const last = ref('Thiessen'); const fullName = computed(() => `${first.value} ${last.value}`); watchEffect(() => console.log(fullName.value));
Maybe it's just me, but for some reason this wasn't all that intuitive at first for me. With the Options API it looks like this: export default { computed: { someComputedProperty() { // Update the computed prop }, }, watch: { someComputedProperty() { // Do something when the computed prop is updated } } };
You can watch: 🎙️ #011 — Learning new Vue Features and Concepts (with LearnVue aka. Matt Maribojoc) In this episode of DejaVue, Michael is joined by Matt Maribojoc, better known as LearnVue on YouTube. While Alex is being absent at VueConf US, Matt and Michael discuss topics around learning and understanding new programming features - from figuring out what the latest features are over to how to properly learn them and eventually teach them to their audience. Tune into the episode to figure out all of the above, in addition to what level of understanding is "necessary" to teach a certain concepts and why content creation is important for libraries, frameworks and open source in general. Watch on YouTube or listen on your favourite podcast platform. Chapters: 00:00 - Guest Introduction - Matt Maribojoc 02:41 - Where and How to Learn New Concepts or Features? 08:50 - How to Explore a New Feature? 19:42 - The Level of Understanding for Teaching 25:38 - Importance of Content for Frameworks and Open Source 31:57 - The Platform Question: YouTube Videos vs. Blog Posts 36:57 - Sharing and Spreading Knowledge of Others 43:27 - Wrapping up In case you missed them: #010 — Design Patterns in Vue.js #009 — Vue.js in Large Applications (with Tim Benniks) #008 — Recap of Vue.js Amsterdam (the biggest Vue Conference) 📜 Suspense: Everything You Need to Know I wrote this article for VueSchool.io to clear up some misconceptions I've seen around Suspense. If you load data in your application, I think you'll find it useful. There are even some code demos so you can code along with the article! Check it out here: Suspense: Everything You Need to Know 📜 Configuration in Nuxt 3: runtimeConfig vs. appConfig Nuxt 3 provides powerful configuration options, allowing you to adapt your application to different use cases. The two key parts of Nuxt 3's configuration system are runtimeConfig and appConfig. This article will explain the purpose and differences between these two options and show you how to use them. Check it out here: Configuration in Nuxt 3: runtimeConfig vs. appConfig 📅 Upcoming Events Here are some upcoming events you might be interested in. Let me know if I've missed any! VueConf CN 2024 — (July 6, 2024) Check it out here PragVue 2024 — (September 17, 2024) The first Czech Vue.js conference, taking place in Cinema City - Nový Smíchov Check it out here Vuejs.de Conf — (October 8, 2024 to October 9, 2024) A community-driven Vue conference in Germany. Listen to great talks from great speakers and meet the wonderful VueJS Community. Check it out here Vue Fes Japan 2024 — (October 19, 2024) Check it out here VueConf Toronto 2024 — (November 18, 2024 to November 20, 2024) My favourite Vue conference, in my own backyard! A three-day event with workshops, speakers from around the world, and socializing. Check it out here 💬 Programmers and designers "If you make a general statement, a programmer says, 'Yes, but...'while a designer says, 'Yes, and...'." — André Bensoussan 🧠 Spaced-repetition: Easy Unit Testing in Nuxt 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. For your unit tests, @nuxt/test-utils lets you opt-in to a Nuxt environment by adding .nuxt. to the filename of your test: ./tests/MyComponent.nuxt.test.ts
You can also add a special comment at the top of the file: @vitest-environment nuxt
Or enable the environment for all Vitest tests in your config: // vitest.config.ts import { defineVitestConfig } from '@nuxt/test-utils/config'; export default defineVitestConfig({ test: { environment: 'nuxt' }, };
|
评论
发表评论