Read this on my blog Mastering Nuxt: Full Stack Unleashed is finally HERE! (well, we launched yesterday) The early bird deal (35% off) is going away soon, so check it out before you miss out: Get Mastering Nuxt here Of course, I have a bunch of tips and other content for you today as well. — Michael 🔥 Overriding styles of a child component — the right way Scoped CSS is fantastic for keeping things tidy and not accidentally bleeding styles into other parts of your app. But sometimes, you need to override the styles of a child component and break out of that scope. Vue has a :deep selector just for this: <style scoped> /* Override CSS of a child component while keeping styles scoped */ .my-component :deep(.child-component) { font-size: 24px; } </style>
In Vue 2 this has a slightly different syntax depending on which CSS pre-processor you're using: <style scoped> /* When using SASS */ .my-component ::v-deep .child-component { font-size: 24px; } /* Everything else */ .my-component >>> .child-component { font-size: 24px; } </style>
Yes, I have previously covered why you shouldn't do this, but overriding styles can be the best solution (we don't believe in "best practices" here). 🔥 Watching Arrays and Objects The trickiest part of using a watcher is that sometimes it doesn't seem to trigger correctly. Usually, this is because you're trying to watch an Array or an Object but didn't set deep to true : watch( colours, () => { console.log('The list of colours has changed!'); }, { deep: true, } );
When using the Options API it would look like this: export default { name: 'ColourChange', props: { colours: { type: Array, required: true, }, }, watch: { // Use the object syntax instead of just a method colours: { // This will let Vue know to look inside the array deep: true, // We have to move our method to a handler field handler() console.log('The list of colours has changed!'); } } } }
🔥 Mount Components When Testing in Nuxt When writing unit tests, you have access to a bunch of helper methods. One super useful one is mountSuspended . It lets you mount any component inside your Nuxt context with async setup: import { describe, it, expect } from 'vitest'; import { mountSuspended } from '@nuxt/test-utils/runtime'; import MyComponent from './MyComponent.vue'; describe('MyComponent', () => { it('renders the message correctly', async () => { const wrapper = await mountSuspended(MyComponent); expect(wrapper.text()).toContain('This component is set up.'); }); });
You're also able to mount your app at a specific route, by passing in the App component and a route: import { describe, it, expect } from 'vitest'; import { mountSuspended } from '@nuxt/test-utils/runtime'; import App from './App.vue'; describe('About', () => { it('renders the about page', async () => { const wrapper = await mountSuspended(App, { route: '/about' }); expect(wrapper.text()).toContain('Hi, my name is Michael!'); }); });
🎙️ #052 — Visualizing Data in Vue (with Dennis Adriaansen) In episode 52 of DejaVue (yes, it is a whole year), Dennis Adriaansen joins Michael and Alex to discuss data visualization in Vue.js. Dennis shares insights about building chart components, his experience with different charting libraries, and introduces his own Vue charting library. They explore topics like chart customization, performance considerations, and integrating charts into dashboards. The conversation also gets into broader topics such as open source sustainability, UI libraries, and backend integrations with Nuxt. Watch on YouTube or listen on your favorite podcast platform. Chapters: 📜 The Testing Pyramid is Dead The testing pyramid is a popular way to think about testing, but it's not a good way. In this article, I explain why the testing pyramid is dead, and what you should be doing instead. Check it out here: The Testing Pyramid is Dead 📜 3 Ways to Create Inline Composables Composables are great, except that it seems we always need to create a new file for them. In this article I explore some ways we can create inline composables — no need to create new files all over the place! Check it out here: 3 Ways to Create Inline Composables 📅 Upcoming Events Here are some upcoming events you might be interested in. Let me know if I've missed any! VueConf US 2025 — (May 13, 2025 to May 15, 2025) Giving a talk here on component patterns! A great Vue conference, this year held in Tampa. Two days of conference talks, plus a day for workshops. Check it out here MadVue 2025 — (May 29, 2025) It's time to get together in Madrid. Join for a full day of talks, activities, and networking with the Vue.js community and ecosystem. Check it out here 💬 The Best Learners "The best learners are the people who push through the discomfort of being objectively bad at something." — Tommy Collison 🧠 Spaced-repetition: Directly accessing parent components (and why) 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. Props down, events up. That's how your components should communicate — most of the time. But in rare cases, that just doesn't work. If you need direct access to the parent component, you should just use provide /inject to pass down the relevant value or method: import { provide } from 'vue'; const someMethodInTheParent = () => {}; provide('method', someMethodInTheParent)
Then, inject it into the child component: import { inject } from 'vue'; const method = inject('method'); method();
In Vue 2, you can also use the instance property $parent : // Tight coupling like this is usually a bad idea this.$parent.methodOnParentComponent();
This is simpler, but leads to higher coupling and will more easily break your application if you ever refactor. You can also get direct access to the application root, the very top-most component in the tree, by using $root . Vue 2 also has $children , but these were taken out for Vue 3 (please don't use this one). When would these be useful? There are a few different scenarios I can think of. Usually, when you want to abstract some behaviour and have it work "magically" behind the scenes. You don't want to use props and events to connect up a component in those cases. Instead, you use provide /inject , $parent , or $root , to automatically connect the components and make things happen. (This is similar to the Compound Component pattern) But it's hard to come up with an example where this is the best solution. Using provide /inject is almost always the better choice. 🔗 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: |
评论
发表评论