Vue.js 101: Mastering Computed Properties and Watchers for Reactive Data
Delia
Posted on May 29, 2024
In Vue.js, computed properties and watchers are powerful tools for managing and reacting to reactive data. Understanding these features is essential for building efficient and responsive Vue.js applications. In this article, we'll explore computed properties and watchers in detail, from beginner to advanced examples, using the Composition API. Let's dive in!
What Are Computed Properties and Watchers?
Computed Properties
Computed properties are reactive data properties that depend on other reactive data properties. They are cached based on their dependencies and will only re-evaluate when one of those dependencies changes. Computed properties are ideal for complex logic that depends on reactive data.
Benefits of Computed Properties:
- Caching: Computed properties are cached based on their dependencies, making them efficient. They only re-compute when one of their dependencies changes.
- Declarative: Computed properties provide a clear and declarative way to describe derived state, making your code more readable and maintainable.
- Simplifies Logic: They are excellent for encapsulating complex calculations or logic that depends on reactive data.
When Not to Use Computed Properties:
- Side Effects: Avoid using computed properties for side effects like API calls or logging. Computed properties should be pure and only return values based on their dependencies.
- Asynchronous Operations: They are not suitable for asynchronous operations, as they are designed to be synchronous.
Watchers
Watchers allow you to perform side effects in response to changing reactive data. Unlike computed properties, which are used for derived state, watchers are primarily used for executing code in reaction to changes, such as making API calls or logging.
Benefits of Watchers:
- Flexibility: Watchers offer more flexibility for executing code in response to data changes. They can handle complex logic that needs to run when data changes.
- Side Effects: Ideal for performing side effects like asynchronous operations, logging, or complex data transformations that are triggered by changes in reactive data.
When Not to Use Watchers:
- Simple Computations: For simple derived state or calculations, use computed properties instead of watchers. Watchers are overkill for these scenarios.
- Declarative Logic: If you can achieve the same result with a computed property, it’s often clearer and more maintainable to use the computed property.
Using the Composition API
Setting Up the Project
Before we start, make sure you have Vue.js installed. Set up a new project using Vue CLI:
npm install -g @vue/cli
vue create vue-computed-watcher
cd vue-computed-watcher
npm run serve
Basic Example with Computed Properties
Let's start with a basic example of computed properties using the Composition API.
Template:
<template>
<div>
<h2>Basic Computed Property Example</h2>
<p>Original Message: {{ message }}</p>
<p>Reversed Message: {{ reversedMessage }}</p>
</div>
</template>
Script:
<script>
import { ref, computed } from 'vue';
export default {
setup() {
const message = ref('Hello Vue.js');
const reversedMessage = computed(() => {
return message.value.split('').reverse().join('');
});
return {
message,
reversedMessage
};
}
};
</script>
-
Reactive Data:
message
is a reactive data property created usingref
. -
Computed Property:
reversedMessage
is a computed property that depends onmessage
. It reverses the string whenevermessage
changes.
Advanced Example with Computed Properties
Now, let's create a more advanced example that includes multiple dependencies and demonstrates the power of computed properties.
Template:
<template>
<div>
<h2>Advanced Computed Property Example</h2>
<p>Items: {{ items.map(item => item.name).join(', ') }}</p>
<p>Total Price: {{ totalPrice }}</p>
</div>
</template>
Script:
<script>
import { ref, computed } from 'vue';
export default {
setup() {
const items = ref([
{ name: 'Apple', price: 1.2 },
{ name: 'Banana', price: 0.8 },
{ name: 'Cherry', price: 2.5 }
]);
const totalPrice = computed(() => {
return items.value.reduce((total, item) => total + item.price, 0).toFixed(2);
});
return {
items,
totalPrice
};
}
};
</script>
-
Reactive Data:
items
is an array of objects, each representing an item with a name and price. -
Computed Property:
totalPrice
calculates the sum of item prices, updating automatically when the items array changes.
Basic Example with Watchers
Watchers are useful for reacting to data changes, such as making an API call or logging information.
Template:
<template>
<div>
<h2>Basic Watcher Example</h2>
<input v-model="name" placeholder="Enter your name" />
<p>Greeting: {{ greeting }}</p>
</div>
</template>
Script:
<script>
import { ref, watch } from 'vue';
export default {
setup() {
const name = ref('');
const greeting = ref('Hello!');
watch(name, (newValue) => {
greeting.value = `Hello, ${newValue}!`;
});
return {
name,
greeting
};
}
};
</script>
-
Reactive Data:
name
andgreeting
are reactive data properties. -
Watcher: The watcher observes
name
and updatesgreeting
whenevername
changes.
Advanced Example with Watchers
For an advanced example, let's perform an asynchronous operation in a watcher.
Template:
<template>
<div>
<h2>Advanced Watcher Example</h2>
<input v-model="query" placeholder="Search for a GitHub user" />
<p v-if="loading">Loading...</p>
<p v-if="error">{{ error }}</p>
<pre v-if="user">{{ user }}</pre>
</div>
</template>
Script:
<script>
import { ref, watch } from 'vue';
export default {
setup() {
const query = ref('');
const user = ref(null);
const loading = ref(false);
const error = ref(null);
const fetchUser = async (username) => {
loading.value = true;
error.value = null;
user.value = null;
try {
const response = await fetch(`https://api.github.com/users/${username}`);
if (!response.ok) throw new Error('User not found');
user.value = await response.json();
} catch (err) {
error.value = err.message;
} finally {
loading.value = false;
}
};
watch(query, (newQuery) => {
if (newQuery) fetchUser(newQuery);
});
return {
query,
user,
loading,
error
};
}
};
</script>
-
Reactive Data:
query
,user
,loading
, anderror
are reactive data properties. -
Watcher: The watcher on
query
triggers thefetchUser
function wheneverquery
changes, performing an asynchronous API call to fetch GitHub user data.
Computed properties and watchers are indispensable tools in Vue.js for managing and reacting to reactive data. Computed properties are ideal for derived state that depends on other reactive data, providing a clear and efficient way to manage complex logic. Watchers, on the other hand, offer flexibility for executing code in response to data changes, making them perfect for side effects such as API calls.
By understanding and effectively using computed properties and watchers, you can build more efficient, responsive, and maintainable Vue.js applications. Whether you're a beginner or looking to advance your skills, mastering these concepts will significantly enhance your Vue.js development experience. Happy coding!
Twitter: @delia_code
Instagram:@delia.codes
Blog: https://delia.hashnode.dev/
Posted on May 29, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.