JAVASCRIPT
Managing Reactive Side Effects with Vue 3 `watchEffect`
Discover how to use Vue 3's `watchEffect` to automatically track reactive dependencies and run side effects, simplifying complex reactivity scenarios.
// App.vue
<template>
<div>
<h1>User Profile Editor</h1>
<label>First Name: </label>
<input v-model="firstName" />
<br />
<label>Last Name: </label>
<input v-model="lastName" />
<br />
<p>Full Name (derived): {{ fullName }}</p>
<p>Last saved at: {{ lastSavedAt }}</p>
</div>
</template>
<script setup>
import { ref, computed, watchEffect } from 'vue';
const firstName = ref('John');
const lastName = ref('Doe');
const lastSavedAt = ref('Never');
// A computed property for full name
const fullName = computed(() => `${firstName.value} ${lastName.value}`);
// watchEffect for auto-saving to local storage
watchEffect((onCleanup) => {
// This effect will re-run whenever firstName or lastName changes
const userProfile = {
firstName: firstName.value,
lastName: lastName.value,
};
// Simulate an API call or local storage save
const timeout = setTimeout(() => {
localStorage.setItem('userProfile', JSON.stringify(userProfile));
lastSavedAt.value = new Date().toLocaleTimeString();
console.log('Profile auto-saved:', userProfile);
}, 1000); // Debounce for 1 second
// Cleanup function (runs when effect is re-run or component unmounted)
onCleanup(() => {
clearTimeout(timeout);
console.log('Previous auto-save attempt cancelled.');
});
});
// Load initial data (optional)
const storedProfile = localStorage.getItem('userProfile');
if (storedProfile) {
const profile = JSON.parse(storedProfile);
firstName.value = profile.firstName || '';
lastName.value = profile.lastName || '';
}
</script>
How it works: This snippet demonstrates `watchEffect` in Vue 3 for managing reactive side effects. Unlike `watch`, `watchEffect` automatically tracks its reactive dependencies, re-running whenever any reactive data accessed inside it changes. Here, it's used to simulate an auto-save feature to local storage, reacting to changes in `firstName` and `lastName`. The `onCleanup` callback is crucial for preventing memory leaks or unwanted side effects (like multiple pending `setTimeout` calls) by clearing them before the effect re-runs or the component is unmounted.