Hey all!
This is a quieter week for me.
I'm mostly heads down working on the big update and re-recording of Mastering Nuxt to bring it all up to date. The code is nearly there, just a little bit of polishing left to make it fantastic.
— Michael
Here’s a nuance to nesting reactive objects that’s tripped me up.
Nesting a ref in a reactive array keeps everything reactive as expected:
const arr = reactive([]);arr.push(ref('hello'));arr.push(ref('world'));setTimeout(() => (arr[0].value = 'nothing'), 1000);
But putting this ref inside a non-reactive object breaks this reactivity:
const arr = reactive([]);arr.push({text: ref('hello'),});arr.push({text: ref('world'),});setTimeout(() => (arr[0].value = 'nothing'), 1000);
I gave a hint in that last sentence — this is because it’s being wrapped in a non-reactive object. The trail of reactivity goes cold once we hit this object, but only because we’re accessing the text property through the non-reactive object.
If we instead access the ref directly, we’re able to trigger a reactive update as expected:
const arr = reactive([]);const one = ref('hello');const two = ref('world');arr.push({text: one,});arr.push({text: two,});// This triggers the update correctlysetTimeout(() => (one.value = 'nothing'), 1000);
Of course, this isn’t about refs in particular. All we need is to keep the reactivity alive, which we can also achieve using reactive.
Yes, mini tips within a tip. It's meta.
Here they are:
use___, create___, on___ref of null, you can update those values later when your logic completes. No need to await around.effectScope to group effects if you have lots of them in your composable. This makes cleaning up your reactivity a lot simpler.
If you have large objects, use shallowRef instead to prevent Vue from recursively making the whole thing reactive. Of course, you'll need to use triggerRef to trigger any reactive effects for it, but it can improve performance.Some tips on making your composables more flexible:
watch, make immediate and flush configurablerefs and primitive values as inputs. By passing the variable through ref, you'll either reuse the existing ref or create a new one.unref if what you need in your composable is a primitive and not a ref.Named slots also have a shorthand syntax, one that's much nicer to look at.
Instead of writing this:
<DataTable><template v-slot:header><TableHeader /></template></DataTable>
We can write this:
<DataTable><template #header><TableHeader /></template></DataTable>
Not a huge difference, but a little cleaner for sure. I think the # character is easier to pick out than v-slot when reading code.
Together with the FormKit author Justin Schroeder, Michael and Alex discuss the challenges of building forms on the internet.
While it seems like a simple task, forms can be complex and pretty time-consuming. Especially when it is more than a Newsletter or Contact Form.
Justin shares his experience building FormKit (multiple times), a form library for Vue.js, and how it can help developers build forms faster and more efficiently. From Accessibility to actually covering edge cases such as form hydration and repopulation!
Of course, we couldn't let Justin go without talking about some of his hot takes from Vue in 2024, over to Vapor Mode, and Tailwind.
Watch on YouTube or listen on your favorite podcast platform.
Chapters:
In case you missed them:
This video from LearnVue shows you the most essential bits of Pinia.
Pinia is the official state management library for Vue 3, so it's definitely worth taking some time to understand it!
Check it out here: Quick Pinia Overview (video)
One of Vue's core features is the use of props. Props are how we pass data around in Vue, from parent to child components.
But not all props are created equal.
There are three main kinds:
Check it out here: 3 Kinds of Props in Vue
Here are some upcoming events you might be interested in. Let me know if I've missed any!
The biggest Vue conference in the world! A two-day event with workshops, speakers from around the world, and socializing.
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.
"A good programmer is someone who always looks both ways before crossing a one-way street." — Doug Linder
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.
It's possible to add global properties to your Vue app in both Vue 2 and Vue 3:
// Vue 3const app = createApp({});app.config.globalProperties.$myGlobal = 'globalpropertiesftw';// Vue 2Vue.prototype.$myGlobal = 'globalpropertiesftw';
I would recommend prefixing any global properties with a $.
This helps prevent naming conflicts with other variables, and it's a standard convention that makes it easy to spot when a value is global.
This global property can be accessed directly off of any component when using the Options API:
computed: {getGlobalProperty() {return this.$myGlobal;},},
Why can't this be used with the composition API?
Because the composition API is designed to be context-free and has no access to this.
Instead, you can create a simple composable to access your globals:
<script setup>import useGlobals from './useGlobals';const { $myGlobal } = useGlobals();</script>
// useGlobals.jsexport default () => ({$myGlobal: 'globalpropertiesftw',});
Michael Hoffman curates a fantastic weekly newsletter with the best Vue and Nuxt links.
p.s. I also have a bunch of products/courses: