Vue3 Api Computed
## Understanding Vue 3 Computed Properties
In Vue 3, **computed properties** allow you to declare values that depend on other reactive data sources.
Instead of writing complex logic directly inside your templates, computed properties let you encapsulate this logic into a single property. This property can then be used in your templates just like any other standard data property.
A computed property automatically tracks its reactive dependencies and updates itself whenever those dependencies change.
---
## Why Use Computed Properties?
1. **Simplified Template Logic**
Writing complex expressions or inline logic inside your HTML templates makes your code difficult to read and maintain. Moving this logic into a computed property keeps your templates clean and declarative.
2. **Performance Optimization (Caching)**
Computed properties are **cached** based on their reactive dependencies. A computed property will only re-evaluate when one of its reactive dependencies changes. If the dependencies remain unchanged, multiple accesses to the computed property will instantly return the previously cached result without re-running the function.
3. **Reactive Updates**
Vueβs reactivity system automatically tracks which reactive variables are accessed inside the computed function. When any of those variables change, Vue triggers a recalculation and updates the DOM accordingly.
---
## Basic Usage and Syntax
In Vue 3's Composition API, computed properties are defined using the `computed()` function imported from the `'vue'` package.
### Example: Full Name Generator
Here is a simple example demonstrating how to combine a first name and a last name into a single computed property:
```javascript
import { ref, computed } from 'vue';
export default {
setup() {
// Define reactive data sources
const firstName = ref('John');
const lastName = ref('Doe');
// Define a computed property
const fullName = computed(() => {
return `${firstName.value} ${lastName.value}`;
});
return {
firstName,
lastName,
fullName,
};
},
};
```
### Code Explanation
1. **`ref` Function**: Used to create reactive state variables. Here, `firstName` and `lastName` are reactive strings.
2. **`computed` Function**: Takes a getter function that returns the computed value. `fullName` automatically tracks `firstName` and `lastName` as dependencies.
3. **Usage in Templates**: You can bind `fullName` directly in your template (e.g., `{{ fullName }}`). Vue automatically unwraps the `.value` of computed properties in templates, just like it does for refs.
---
## The Caching Mechanism
To understand how caching works, consider the following example:
```javascript
import { ref, computed } from 'vue';
const count = ref(0);
const doubleCount = computed(() => {
console.log('Calculating doubleCount...'); // This runs only when count changes
return count.value * 2;
});
// First access: executes the getter function and caches the result
console.log(doubleCount.value); // Output: "Calculating doubleCount..." followed by 0
// Second access: returns the cached result directly without executing the function
console.log(doubleCount.value); // Output: 0
// Update the dependency
count.value = 2;
// Third access: dependency changed, so it recalculates
console.log(doubleCount.value); // Output: "Calculating doubleCount..." followed by 4
```
---
## Computed Properties vs. Methods
While you can achieve the same visual output using either a computed property or a method, they differ significantly in execution:
| Feature | Computed Properties | Methods |
| :--- | :--- | :--- |
| **Caching** | Cached based on reactive dependencies. | Never cached; executes on every render/call. |
| **Performance** | Highly efficient for expensive operations. | Can cause performance bottlenecks if called frequently in templates. |
| **Usage Scenario** | Best for deriving state from existing reactive data. | Best for handling user events or performing actions. |
### Code Comparison
```javascript
import { ref, computed } from 'vue';
const count = ref(0);
// 1. Using a computed property (Cached)
const doubleCount = computed(() => count.value * 2);
// 2. Using a method (Not Cached)
function getDoubleCount() {
return count.value * 2;
}
```
---
## Advanced Usage: Writable Computed Properties
By default, computed properties are **read-only**. If you attempt to assign a new value to a computed property, Vue will emit a runtime warning.
However, you can create a **writable** computed property by providing an object with both a `get` and a `set` function:
```javascript
import { ref, computed } from 'vue';
const firstName = ref('John');
const lastName = ref('Doe');
const fullName = computed({
// Getter: returns the computed value
get() {
return `${firstName.value} ${lastName.value}`;
},
// Setter: triggers when you assign a new value to fullName.value
set(newValue) {
const names = newValue.split(' ');
firstName.value = names || '';
lastName.value = names || '';
}
});
// Example usage:
fullName.value = 'Jane Smith';
console.log(firstName.value); // Output: "Jane"
console.log(lastName.value); // Output: "Smith"
```
---
## Best Practices and Considerations
* **Keep Getters Side-Effect Free**: The getter function of a computed property should only perform pure calculations and return a value. Do not mutate other state, make asynchronous API requests, or manipulate the DOM inside a computed getter. For side effects, use Vue's `watch` or lifecycle hooks instead.
* **Avoid Mutating Computed Values Directly**: Unless you have defined a custom setter (writable computed), treat computed properties as read-only snapshots. Always update the source reactive state (the dependencies) to trigger a recalculation.
YouTip