I hope you're having a great week! I've been hard at work, digging into different parts of Nuxt that I've never used before and learning a lot. All so I can have some really great tips for the upcoming Nuxt Tips Collection. But I took a break from that this week and did my first live streams — we built Vuedle, a Wordle clone that uses Nuxt server components and ships minimal JS. You can catch part 1 and part 2 on YouTube. I plan to do a livestream each week. For now, slowly working on this app and adding more fun stuff to it. Enjoy the rest of the newsletter! — Michael 🔥 Private properties with script setup You can limit what properties are available when a component is accessed by $ref : export default { expose: ['makeItPublic'], data() { return { privateData: 'Keep me a secret!', }; }, computed: { makeItPublic() { return this.privateData.toUpperCase(); }, }, };
With only makeItPublic exposed, you can't access the privateData property through a $ref anymore: this.$refs.component.privateData // Will always be undefined
<script setup> import { ref, computed } from 'vue'; const privateData = ref('Keep me a secret!'); const makeItPublic = computed( () => privateData.value.toUpperCase() ); // We don't need to import this because it's a compiler macro defineExpose({ makeItPublic }); </script>
Here defineExpose is a compiler macro, not an actual function, so we don't have to import anything. You can find more info on this in the docs. 🔥 Directives in Render Functions Vue comes with some methods to help you use custom directives on your VNodes: <script setup> import { resolveDirective, withDirectives, h } from 'vue'; // Find the already registered directive by name const focusDirective = resolveDirective('focus'); // Wrap the button with the directive const render = () => withDirectives( h('button', {}, []), // An array of directives to apply [ [focusDirective] ] ); </script>
You can find more info on using withDirectives on the docs. 🔥 The Hidden Component Pattern Looking at a component itself is the primary way that we can figure out when and how to refactor it. But we can also look at how the component is used for some clues. Specifically, we're looking to see if there are subsets of this component where those features are only used together. This suggests that there may be more than one component hidden inside of this one. Let's say we have the following component: <template> <div v-if="conditional"> <!-- ... --> </div> <div v-else> <!-- ... --> </div> </template>
Because the v-if is at the root, we know that it's not actually adding any value to this component. Instead, we can simplify by splitting into one component for each branch of our conditional: <template> <ComponentWhereConditionalIsTrue /> <ComponentWhereConditionalIsFalse /> </template>
Now, we don't need to hard-code the conditional prop — we can just use the more descriptive and specific component. For another example, if prop1 and prop2 are only ever used together, but never with prop3 and prop4 , it could mean that the functionality relying on prop1 and prop2 should be separated from the rest of the component. In this illustration, the usage of MyComponent always uses two distinct sets of props, prop1 and prop2 , or prop3 and prop4 : <MyComponent prop-1="someValue" prop-2="anotherValue" /> <MyComponent prop-1="hello" prop-2="world" /> <MyComponent :prop-3="34" prop-4 />
In our theoretical refactoring, we would split the component to work like this: <FirstComponent prop-1="someValue" prop-2="anotherValue" /> <FirstComponent prop-1="hello" prop-2="world" /> <SecondComponent :prop-3="34" prop-4 />
Here are the steps to do this refactoring: - Look for how the component is being used
- Identify any subsets of behaviour — props, events, slots, etc. — that don't overlap
- Simplify using other patterns until it's easy to understand
- Refactor into separate components based on the subsets of behaviour
Learn more about this pattern in the Clean Components Toolkit. 🎙️ #013 — The Road to Nuxt 4 (with Daniel Roe) Nuxt 4 is cooking for a while and is close to being released soon. An ideal time for a DejaVue episode where Michael and Alex we explore the upcoming major version of the metaframework with the lead of the Nuxt team, Daniel Roe. Watch on YouTube or listen on your favourite podcast platform. Chapters: In case you missed them: 📜 The Best Resources for Learning Vue in 2024 In the ever-evolving world of web development, staying updated with the latest tools and techniques is so important, yet it can be so difficult. In this guide, I've curated a selection of Vue 3 courses that I believe will really help both beginners and seasoned developers alike. Check it out here: The Best Resources for Learning Vue in 2024 📅 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 💬 First Do It "First do it, then do it right, then do it better." — Addy Osmani 🧠 Spaced-repetition: Proxy Basics 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. Proxies are one of the strangest but most interesting parts of Javascript. It's a fancy wrapper that lets us create lightweight reactivity systems like in Vue, and so much more. Defining a proxy is simple. We just need to create a handler object, and then use it on an object: const handler = { get(target, prop, receiver) { return 'proxied!'; }, }; const someObj = { hello: 'world', }; const proxy = new Proxy(someObj, handler); console.log(proxy.hello) // proxied!
It lets us intercept property accesses with the get "trap", so we could force any object to use our own logging method: const handler = { get(target, prop, receiver) { return () => { if (typeof target[prop] !== "function") return; // Force the method to use our own logging method const consoleLog = console.log; console.log = (msg) => { consoleLog(`[${prop}] ${msg}`); }; target[prop](); console.log = consoleLog; }; }, }; const someObj = { hello() { console.log('world'); } } const proxy = new Proxy(someObj, handler); proxy.hello() // [hello] world
|
评论
发表评论