Read this on my blog Hi! This week is a bit quieter for me. I just wrapped up the launch of Advanced Reactivity, so I'm switching gears a little. So, no new articles for you this week, but I've got some from the archives that you might have missed! And of course, your tips, as always. Have a fantastic week! — Michael 🔥 Writable Computed Refs Computed refs are cool and all, but did you know you can create writable computed refs? const firstName = ref(''); const lastName = ref(''); const fullName = computed({ get: () => `${firstName.value} ${lastName.value}`, set: (val) => { const split = val.split(' '); // ['Michael', 'Thiessen'] firstName.value = split[0]; // 'Michael' lastName.value = split[1]; // 'Thiessen' } }); fullName.value = 'Michael Thiessen'; console.log(lastName.value); // 'Thiessen'
If you want to learn more about writable computed refs (and other advanced reactivity patterns), check out my course Advanced Reactivity. 🔥 When to use the Hidden Component Pattern It's just as important to know when not to use a pattern as it is to know how to use a pattern. For Hidden Components, it comes down to whether we're dealing with dynamic, reactive values, or values that are hard-coded. Following this pattern we factor out the collapse prop. We end up with two components, for when collapse is true and for when it's false : <!-- `collapse` is true --> <ArticlesCollapsed /> <!-- `collapse` is true --> <ArticlesExpanded />
But if we always use these components where we're dynamically switching between them, we now have to use an extra wrapper component: <!-- Articles.vue --> <template> <ArticlesCollapsed v-if="collapse" /> <ArticlesExpanded v-else /> </template>
Our code is easier to understand, but we haven't necessarily simplified our code. In a way, we're back to where we started, switching between behaviours based on the collapse prop. This is because if we always use collapse dynamically, then the collapsed and expanded versions aren't really separate components anymore. They're two distinct ways of using the same component. So in this case, if we're only using collapse dynamically, we don't gain much by having separated these components. Yes, it is more organized, but not much simpler. But we may mix dynamic and hard-coded usage of this component throughout our app. This makes our wrapper component quite useful, since we now have three options to choose from now. Each one very clearly shows the intended usage, making our code easy to understand: <ArticlesCollapsed /> <ArticlesExpanded /> <Articles :collapse="isCollapsed" />
To sum up: - Replace hard-coded usage with
ArticlesCollapsed and ArticlesExpanded - Replace dynamic usage with the wrapper component
Learn more about this pattern in the Clean Components Toolkit. 🔥 Using Render Functions for Dynamic Component Logic Render functions provide a powerful and flexible way to programmatically define the output of components. This approach is particularly useful when you need more control over the rendering process than templates offer. Consider a scenario where you're building a custom If...Else component that conditionally renders content based on a given condition (we're just doing this for fun, okay?) Here's a simplified example of how you might use a render function in an If component: export default { props: ['val'], setup(props, { slots }) { return () => { const children = []; if (props.val && slots.true) { children.push(slots.true()); } else if (!props.val && slots.false) { children.push(slots.false()); } return children; }; }, };
In this example, the If component takes a val prop to determine which slot to render — true or false . The render function checks props.val and dynamically decides which slot to render based on its value. Render functions are especially useful when: - You need to programmatically construct component output based on complex conditions.
- You're building higher-order components that manipulate their children in ways that aren't straightforward with templates.
- You want to leverage JavaScript's full power to dynamically generate component structures.
While render functions offer great power and flexibility, they come at the cost of reduced readability and simplicity compared to template syntax. So it's generally recommended to use them only when necessary, keeping the balance between functionality and maintainability. 📜 How to access DOM elements with useTemplateRef Learn how to access DOM elements with the useTemplateRef composable. I went deep into the useTemplateRef composable, and how it compares to the old way of accessing DOM elements. I also share some best practices for using this composable! Check it out here: How to access DOM elements with useTemplateRef 📜 Prisma with Nuxt: Creating the Prisma Schema (2 of 5) Trying to manage database schemas alongside your Nuxt app types can be a challenge. But with Prisma, most of these problems go away. It handles all of the boilerplate and coordination, so you just write one single schema that's used in your database and in your TypeScript app. In this article I show you how to create your Prisma schema. Check it out here: Prisma with Nuxt: Creating the Prisma Schema (2 of 5) 💬 Technical Debt "The code we release will be imperfect. Not buggy. Imperfect. There's a difference. We know as a fact that some of what our code does will be wrong; we just don't know exactly what will be wrong. That's tech debt." — Allen Holub 🧠 Spaced-repetition: Vue to Web Component in 3 Easy Steps 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. Here's how you can create web components in Vue. First, create the custom element from a Vue component using defineCustomElement : import { defineCustomElement } from 'vue'; import MyVueComponent from './MyVueComponent.vue'; const customElement = defineCustomElement(MyVueComponent);
Second, register the custom element with the DOM: customElements.define('my-vue-component', customElement);
Third, use the custom element in your HTML: <html> <head></head> <body> <my-vue-component></my-vue-component> </body> </html>
Now you've got a custom web component that doesn't need a framework and can run natively in the browser! Check out the docs for more details on how this works. 🔗 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: |
评论
发表评论