Hey all!
Yesterday I gave my talk on Nuxt server components at Nuxt Nation (which is currently still happening if you want to check it out).
Next week I'll be giving a talk on Nuxt layers at VueConf Toronto.
Other than that, I hope you're having a great week!
Enjoy the tips, new podcast episode, and articles.
— Michael
If you ever need to implement dragging or to move something along with the mouse, here's how you do it:
requestAnimationFrame
. Lodash's throttle
method with no wait
parameter will do this. If you don't throttle, your event will fire faster than the screen can even refresh, and you'll waste CPU cycles and the smoothness of the movement.Here's a basic example of tracking mouse movements using the Composition API. I didn't include throttling in order to keep things clearer:
// In your setup() functionwindow.addEventListener("mousemove", (e) => {// Only move the element when we're holding down the mouseif (dragging.value) {// Calculate how far the mouse moved since the last// time we checkedconst diffX = e.clientX - mouseX.value;const diffY = e.clientY - mouseY.value;// Move the element exactly how far the mouse movedx.value += diffX;y.value += diffY;}// Always keep track of where the mouse ismouseX.value = e.clientX;mouseY.value = e.clientY;});
Here's the full example. You can check out a working demo here:
<template><div class="drag-container"><imgalt="Vue logo"src="./assets/logo.png":style="{left: `${x}px`,top: `${y}px`,cursor: dragging ? 'grabbing' : 'grab',}"draggable="false"@mousedown="dragging = true"/></div></template>
<script setup>import { ref } from "vue";const dragging = ref(false);const mouseX = ref(0);const mouseY = ref(0);const x = ref(100);const y = ref(100);window.addEventListener("mousemove", (e) => {if (dragging.value) {const diffX = e.clientX - mouseX.value;const diffY = e.clientY - mouseY.value;x.value += diffX;y.value += diffY;}mouseX.value = e.clientX;mouseY.value = e.clientY;});window.addEventListener("mouseup", () => {dragging.value = false;});</script>
One thing that’s a little tedious with refs is when you need to access a nested property within the template:
<template><div id="app"><p v-for="el in arr">{{ el.value.text }}</p></div></template>
const arr = reactive([]);arr.push(ref({ text: 'hello' }));arr.push(ref({ text: 'world' }));setTimeout(() => (arr[0].value.text = 'nothing'), 1000);
You can’t just rely on auto-unwrapping of refs, you have to explicitly access the .value
and then grab the nested property from there:
ref.value.nestedProperty
In this case, using a reactive
value might be preferable — if the syntax is really bothering you.
If you've ever written unit tests, you'll have needed to mock out API endpoints that are used in your components or stores.
With @nuxt/test-utils
this is really simple, because you get the registerEndpoint
utility method:
import { registerEndpoint } from '@nuxt/test-utils/runtime';import userTestData from './userTestData.json';registerEndpoint('/users/', () => userTestData);// ...tests
You can mock any server route (API endpoint), including external endpoints if you need.
Alex is accompanied by the wonderful CJ Reynolds in this episode of DejaVue. The Senior Creator at Syntax.fm brings not only Vue experience but also a history of Angular JS and React, as well as various other technologies.
The two content creators talk about how CJ became a senior creator at the well-known Syntax.fm podcast and how it is different from streaming on Twitch and his previous content creation processes. Further, CJ gives insights on how the Denver Vue meetup evolved (now the DenverScript meetup) and shares some hopes when it comes to the meetup scene.
Alex and CJ then discuss more technical topics - for example why CJ never fully switched over to Vue but still writes it a lot.
The discussion eventually goes into comparisons between Vue and React, highlighting what Vue does "better" than React and how the Vue ecosystem shapes the web development work.
Watch on YouTube or listen on your favorite podcast platform.
Chapters:
In case you missed them:
Nuxt gives us a few different options for controlling when components are loaded.
In this article I explore the different options and how to use each.
Check it out here: Controlling When Components Are Loaded in Nuxt
Custom error pages are a great way to give your users a better experience when something goes wrong.
In this article, we'll go over how to create them in Nuxt.
Check it out here: Custom Error Pages in Nuxt
Here are some upcoming events you might be interested in. Let me know if I've missed any!
My favourite Vue conference, in my own backyard! A three-day event with workshops, speakers from around the world, and socializing. I will be speaking on Nuxt Layers!
The biggest Vue conference in the world! A two-day event with workshops, speakers from around the world, and socializing.
"The best reaction to "this is confusing, where are the docs" is to rewrite the feature to make it less confusing, not write more docs." — Jeff Atwood
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.
You don’t have to decide between Options API and Composition API, you can use both:
export default {setup() {const darkMode = ref(false);return { darkMode }},methods: {saveDarkMode() {localStorage.setItem('dark-mode', this.darkMode);},}};
We can also update values from the Options API:
export default {setup() {const darkMode = ref(false);return { darkMode }},methods: {changeTheme(val) {this.darkMode = val;}}};
Although you can access Composition API from the Options API, it’s a one-way street. The Composition API cannot access anything defined through the Options API:
export default {setup() {const darkMode = ref(false);// We can't access the methodthis.changeTheme(true);return { darkMode }},methods: {changeTheme(val) {this.darkMode = val;}}
This can be useful for incremental adoption of the Composition API, because it lets you use reusable composables in your Options API.
But mixing two styles of writing components is likely to cause more headaches than it solves, so please think twice before doing this!
Michael Hoffman curates a fantastic weekly newsletter with the best Vue and Nuxt links.
p.s. I also have four products/courses: Clean Components Toolkit, Vue Tips Collection 2, Mastering Nuxt 3, and Reusable Components