Vue Computed Properties
Efficient reactive calculations in Vue
⚡ What are Computed Properties?
Computed properties are cached reactive values based on their dependencies. They automatically update when dependencies change and are more efficient than methods for complex calculations.
<div id="app">
<p>{{ fullName }}</p>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script>
Vue.createApp({
data() {
return {
firstName: 'John',
lastName: 'Doe'
}
},
computed: {
fullName() {
return this.firstName + ' ' + this.lastName
}
}
}).mount('#app')
</script>
Computed Properties Benefits
Cached
Results are cached until dependencies change
Reactive
Automatically updates when data changes
Efficient
Only recalculates when needed
Readable
Cleaner template syntax than methods
🔹 Basic Computed Property
Computed properties are defined in the computed option. They work like data properties but are calculated based on other reactive data.
<div id="app">
<input v-model="firstName" placeholder="First name">
<input v-model="lastName" placeholder="Last name">
<p>Full Name: {{ fullName }}</p>
<p>Reversed: {{ reversedName }}</p>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script>
Vue.createApp({
data() {
return {
firstName: 'John',
lastName: 'Doe'
}
},
computed: {
fullName() {
return this.firstName + ' ' + this.lastName
},
reversedName() {
return this.fullName.split('').reverse().join('')
}
}
}).mount('#app')
</script>
Output:
Full Name: John Doe
Reversed: eoD nhoJ
🔹 Computed vs Methods
While methods and computed properties can achieve similar results, computed properties are cached and only re-evaluate when dependencies change, making them more efficient.
Key Differences:
- Computed: Cached, only recalculates when dependencies change
- Methods: Always runs when called, no caching
- Use Computed: For calculations based on reactive data
- Use Methods: For actions or when you need to pass parameters
<div id="app">
<p>Computed: {{ computedPrice }}</p>
<p>Method: {{ calculatePrice() }}</p>
<button @click="quantity++">Add Item</button>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script>
Vue.createApp({
data() {
return {
price: 10,
quantity: 1
}
},
computed: {
computedPrice() {
console.log('Computed called')
return this.price * this.quantity
}
},
methods: {
calculatePrice() {
console.log('Method called')
return this.price * this.quantity
}
}
}).mount('#app')
</script>
🔹 Computed Property with Getter and Setter
Computed properties can have both getter and setter functions. This allows you to modify the computed value, which then updates the underlying data.
<div id="app">
<input v-model="fullName" placeholder="Enter full name">
<p>First: {{ firstName }}</p>
<p>Last: {{ lastName }}</p>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script>
Vue.createApp({
data() {
return {
firstName: 'John',
lastName: 'Doe'
}
},
computed: {
fullName: {
// Getter
get() {
return this.firstName + ' ' + this.lastName
},
// Setter
set(newValue) {
const names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
}).mount('#app')
</script>
Output:
First: John
Last: Doe
🔹 Practical Example: Shopping Cart
Here's a practical example using computed properties to calculate shopping cart totals:
<div id="app">
<h3>Shopping Cart</h3>
<div v-for="item in items" :key="item.id">
<span>{{ item.name }}: ${{ item.price }} x {{ item.quantity }}</span>
<button @click="item.quantity++">+</button>
<button @click="item.quantity--">-</button>
</div>
<p>Subtotal: ${{ subtotal }}</p>
<p>Tax (10%): ${{ tax }}</p>
<p><strong>Total: ${{ total }}</strong></p>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script>
Vue.createApp({
data() {
return {
items: [
{ id: 1, name: 'Book', price: 10, quantity: 2 },
{ id: 2, name: 'Pen', price: 2, quantity: 5 }
]
}
},
computed: {
subtotal() {
return this.items.reduce((sum, item) => {
return sum + (item.price * item.quantity)
}, 0)
},
tax() {
return (this.subtotal * 0.1).toFixed(2)
},
total() {
return (parseFloat(this.subtotal) + parseFloat(this.tax)).toFixed(2)
}
}
}).mount('#app')
</script>
Output:
Shopping Cart
Subtotal: $30
Tax (10%): $3.00
Total: $33.00
🔹 Filtering and Sorting Lists
Computed properties are perfect for filtering and sorting data without modifying the original array:
<div id="app">
<input v-model="searchQuery" placeholder="Search...">
<ul>
<li v-for="user in filteredUsers" :key="user.id">
{{ user.name }} - {{ user.age }} years old
</li>
</ul>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script>
Vue.createApp({
data() {
return {
searchQuery: '',
users: [
{ id: 1, name: 'Alice', age: 25 },
{ id: 2, name: 'Bob', age: 30 },
{ id: 3, name: 'Charlie', age: 22 },
{ id: 4, name: 'David', age: 28 }
]
}
},
computed: {
filteredUsers() {
return this.users.filter(user => {
return user.name.toLowerCase()
.includes(this.searchQuery.toLowerCase())
})
}
}
}).mount('#app')
</script>
Output:
- Alice - 25 years old
- Bob - 30 years old
- Charlie - 22 years old
- David - 28 years old