Skip to main content
Practice Problems

Computed, methods and watchers in Vue.js

Introduction

Vue has three ways to work with reactive data: computed, methods, and watchers. Each has its purpose and characteristics.


Computed Properties

Computed properties are calculated based on other reactive data and are cached.

Composition API

javascript
<template> <p>First Name: {{ firstName }}</p> <p>Last Name: {{ lastName }}</p> <p>Full Name: {{ fullName }}</p> </template> <script setup> import { ref, computed } from 'vue' const firstName = ref('John') const lastName = ref('Doe') const fullName = computed(() => { return `${firstName.value} ${lastName.value}` }) </script>

Key Features

Caching

Result is calculated only when dependencies change:

javascript
<script setup> import { ref, computed } from 'vue' const count = ref(0) const doubleCount = computed(() => { console.log('Computing...') // Called only when count changes return count.value * 2 }) </script> <template> <p>{{ doubleCount }}</p> <p>{{ doubleCount }}</p> <p>{{ doubleCount }}</p> <!-- console.log called only once --> </template>

Writable Computed

javascript
<script setup> import { ref, computed } from 'vue' const firstName = ref('John') const lastName = ref('Doe') const fullName = computed({ get() { return `${firstName.value} ${lastName.value}` }, set(newValue) { [firstName.value, lastName.value] = newValue.split(' ') } }) // Usage fullName.value = 'Jane Smith' // firstName.value = 'Jane' // lastName.value = 'Smith' </script>

Methods

Methods are functions that execute every time they're called.

javascript
<template> <p>{{ getFullName() }}</p> <button @click="greet">Greet</button> </template> <script setup> import { ref } from 'vue' const firstName = ref('John') const lastName = ref('Doe') function getFullName() { console.log('Method called') return `${firstName.value} ${lastName.value}` } function greet() { alert(`Hello, ${getFullName()}!`) } </script>

Key Features

No Caching

javascript
<template> <p>{{ getFullName() }}</p> <p>{{ getFullName() }}</p> <p>{{ getFullName() }}</p> <!-- console.log called 3 times --> </template>

Accept Arguments

javascript
<template> <p>{{ formatPrice(100) }}</p> <p>{{ formatPrice(250, 'USD') }}</p> </template> <script setup> function formatPrice(price, currency = 'USD') { return `${price} ${currency}` } </script>

Watchers

Watchers are functions that react to data changes and perform side effects.

javascript
<template> <input v-model="searchQuery" placeholder="Search..." /> </template> <script setup> import { ref, watch } from 'vue' const searchQuery = ref('') watch(searchQuery, (newValue, oldValue) => { console.log(`Changed from "${oldValue}" to "${newValue}"`) // Perform API request fetchResults(newValue) }) function fetchResults(query) { // API request } </script>

Key Features

Watch Multiple Sources

javascript
<script setup> import { ref, watch } from 'vue' const firstName = ref('') const lastName = ref('') watch([firstName, lastName], ([newFirst, newLast]) => { console.log(`Full name: ${newFirst} ${newLast}`) }) </script>

Immediate Execution

javascript
<script setup> import { ref, watch } from 'vue' const count = ref(0) watch(count, (newValue) => { console.log('Count changed:', newValue) }, { immediate: true }) // Called immediately on creation </script>

Deep Watching

javascript
<script setup> import { reactive, watch } from 'vue' const user = reactive({ name: 'John', address: { city: 'New York' } }) watch(user, (newValue) => { console.log('User changed:', newValue) }, { deep: true }) // Triggers even when user.address.city changes user.address.city = 'Los Angeles' </script>

Comparison

Computed vs Methods

PropertyComputedMethods
CachingYesNo
ReactivityAutomaticManual
ArgumentsNoYes
Usage in template{{ computed }}{{ method() }}
Side effectsNot recommendedAllowed

When to use computed:

  • Calculate based on other data
  • Need caching
  • Synchronous operations

When to use methods:

  • Event handlers
  • Need parameters
  • Side effects (API requests, data changes)

Computed vs Watchers

PropertyComputedWatchers
PurposeCalculate valueSide effects
ResultReturns valueNo return
DependenciesAutomaticExplicit
AsyncNoYes

Common Mistakes

Using methods instead of computed

javascript
<!-- Inefficient --> <template> <p>{{ getFullName() }}</p> <p>{{ getFullName() }}</p> <!-- Called twice --> </template> <!-- Efficient --> <template> <p>{{ fullName }}</p> <p>{{ fullName }}</p> <!-- Calculated once --> </template> <script setup> import { computed } from 'vue' const fullName = computed(() => { return `${firstName.value} ${lastName.value}` }) </script>

Side effects in computed

javascript
<!-- Wrong --> <script setup> import { computed, ref } from 'vue' const count = ref(0) const doubled = ref(0) const bad = computed(() => { doubled.value = count.value * 2 // Side effect! return count.value * 2 }) </script> <!-- Correct - use watcher --> <script setup> import { watch, ref } from 'vue' const count = ref(0) const doubled = ref(0) watch(count, (newCount) => { doubled.value = newCount * 2 }) </script>

Conclusion

Computed:

  • Calculate values based on other data
  • Automatic caching
  • Synchronous operations

Methods:

  • Event handlers
  • Functions with parameters
  • Side effects

Watchers:

  • React to changes
  • Asynchronous operations
  • Side effects (API, localStorage)

In interviews:

Important to be able to:

  • Explain the difference between computed, methods and watchers
  • Describe caching in computed
  • Give examples of when to use each
  • Explain performance issues with wrong choice

Content

IntroductionComputed PropertiesComposition APIKey FeaturesMethodsKey FeaturesWatchersKey FeaturesComparisonComputed vs MethodsComputed vs WatchersCommon MistakesUsing methods instead of computedSide effects in computedConclusion

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems