🔥 (#133) Writable Computed Refs
Hey all,
Don't forget that I'm giving a workshop at VueConf Toronto this year on November 9th!
We'll be going over some advanced Vue patterns and techniques, and you'll have time to apply them to your own code and really dig into them.
This is also a chance to discuss these concepts with other Vue devs and hone your understanding — I'm really excited for this!
If you're interested, you can get your ticket for the workshop and the conference here.
Enjoy your tips this week!
— Michael
Vue Tips Collection
Maybe you just want to stay on top of the latest features, remind yourself of interesting things Vue can do, and get daily inspiration.
Vue Tips Collection is a beautiful book of 115 awesome tips, as well as a daily email to get your creative juices flowing.
🔥 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'
🔥 Components are Functions
Underneath it all, components are just functions that return some HTML.
It's a huge simplification, and if you've ever looked at the complexity of the Vue codebase you know this isn't actually true. But, fundamentally, this is what Vue is doing for us — plus a million other amazing things.
Take a look at this component:
<template> <div> <h1>{{ title }}</h1> <p>Some words that describe this thing</p> <button>Clickity click!</button> </div> </template>
Now, here is some Javascript that does essentially the same thing:
function component(title) { let html = ''; html += '<div>'; html += `<h1>${title}</h1>`; html += '<p>Some words that describe this thing</p>'; html += '<button>Clickity click!</button>'; html += '</div>'; return html; }
This code constructs the HTML in much the same way that the Vue component would.
Granted, we don't get reactivity, event handling, or a bunch of other features with this, but the HTML that gets output is the same thing.
This means that we can apply all of the patterns and experience from Javascript (and other languages) to our components. Things like breaking components down into smaller pieces, naming them well, and avoiding over-abstraction are all examples.
Of course, there are many more!
🔥 Improve reusability by converting template props into slots
One kind of prop, a template prop, can be directly converted into slots without very much work.
This makes your component more reusable.
The text
prop here is a template prop, because it is only ever used in the template:
<template> <button @click="$emit('click')"> {{ text }} </button> </template> <script setup> const props = defineProps({ text: { type: String, required: true, }, }); defineEmits(['click']); </script>
It doesn't get used in any calculations or passed as a prop anywhere. Instead, it just gets directly interpolated and rendered to the page.
These props can be directly replaced with slots:
<template> <button @click="$emit('click')"> <slot /> </button> </template> <script setup> defineEmits(['click']); </script>
This sort of cleans up the code, but more importantly, it allows us to be more flexible with how the component can be used.
With a prop we have to use the component like this:
<Button text="Click me" @click="handleClick" />
But with a slot, we can add in whatever we want:
<Button @click="handleClick"> Click on <strong>this</strong> button </Button>
📜 Compressing Images with Vite and VSharp
Images are one of the biggest causes of slow webpages.
We have a bunch of strategies for dealing with this, but the most basic one is to make sure each and every image in your app is compressed as much as possible.
Fortunately for us, setting up Nuxt to automatically compress our images only takes a few minutes.
Check it out here: Compressing Images with Vite and VSharp
💬 Better Not Start
"Programming is just saying "I have a meeting in an hour so better not start on this yet" to yourself until you die." — Alex Engelberg
🧠 Spaced-repetition: When should you use v-if?
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.
Instead of using v-if
, it's sometimes more performant to use v-show
instead:
<ComplicatedChart v-show="chartEnabled" />
When v-if
is toggled on and off, it will create and destroy the element completely. Instead, v-show
will create the element and leave it there, hiding it by setting its style to display: none
.
Doing this can be much more efficient if the component you're toggling is expensive to render.
On the flip side, if you don't need that expensive component immediately, use v-if
so that it will skip rendering it and load the page just a bit faster.
p.s. I also have four products to help you learn Vue: Clean Components Toolkit, Vue Tips Collection, Mastering Nuxt 3 and Reusable Components
评论
发表评论