Vue Methods vs Computed Properties: Core Differences and When to Use Each

TLDR: In Vue.js, methods are imperative functions that run on every invocation without caching, while computed properties are reactive, memoized getters that only re-evaluate when dependencies change. Use methods for actions and side effects; use computed properties for deriving state from reactive data efficiently.

Understanding when to use methods and computed properties in Vue is critical for application performance and architecture. In the vuejs/core repository, these features are implemented through distinct mechanisms in the reactivity and runtime-core packages. While both are declared in the component options object, they serve fundamentally different purposes in the component's reactivity system.

How Vue Methods Work

Methods in Vue are simple functions registered under the methods option in ComponentOptionsBase. During component initialization, the runtime iterates over options.methods and binds each function to the component instance.

In packages/runtime-core/src/componentOptions.ts (lines 91–118), the applyOptions function registers methods by binding them to the public instance proxy:

ctx[key] = methodHandler.bind(publicThis)

This binding ensures that this inside any method refers to the component's public proxy, giving access to data, props, and other options. Methods are not reactive—they execute immediately when called and do not track dependencies or cache results.

Characteristics of Methods

  • Imperative execution: Run only when explicitly invoked (e.g., @click="handleClick")
  • No caching: Return values are calculated fresh on every call
  • Side-effect friendly: Designed for mutating state, API calls, and event handling
  • Function syntax: Must be called with parentheses in templates

How Computed Properties Work

Computed properties are reactive getters defined under the computed option. Unlike methods, they leverage Vue's reactivity system through ComputedRefImpl in packages/reactivity/src/computed.ts.

When a component initializes computed properties, applyOptions in packages/runtime-core/src/componentOptions.ts (lines 59–94) creates a ComputedRefImpl instance and defines it on the component proxy:

Object.defineProperty(ctx, key, {
  get: () => c.value,
  set: v => (c.value = v)
})

The ComputedRefImpl class tracks reactive dependencies accessed during the getter execution. As implemented in packages/reactivity/src/computed.ts (lines 31–40), the computed value only recalculates when dependencies change via the refreshComputed mechanism; otherwise, it returns the cached result.

Characteristics of Computed Properties

  • Reactive caching: Results are memoized until dependencies mutate
  • Property syntax: Accessed as values ({{ total }}) without parentheses
  • Pure derivations: Intended for transforming reactive data without side effects
  • Automatic updates: UI re-renders automatically when cached value becomes dirty

Key Differences

Feature Methods Computed Properties
Reactivity Non-reactive; no dependency tracking Reactive; tracks all dependencies in getter
Caching No caching; executes on every call Memoized; only re-evaluates when deps change
Template Usage Called as functions (@click="submit()") Accessed as properties ({{ fullName }})
Side Effects Appropriate for mutations and I/O Discouraged; should be pure functions
Binding Bound via methodHandler.bind(publicThis) Getter/setter bound via getter.bind(publicThis)

When to Use Each Approach

Use Methods For:

  • Event handling: Responding to user interactions like clicks, submits, or input events
  • Mutations: Changing component state or calling APIs when explicit action occurs
  • Parameterization: Logic that requires arguments passed at call time
  • Imperative operations: Tasks that should run on-demand rather than automatically

Use Computed Properties For:

  • Derived state: Calculating values based on existing reactive data (e.g., filtering lists, formatting dates)
  • Expensive calculations: Operations that should avoid redundant execution through caching
  • Read-only or writable derived data: Two-way computed properties that sync with source data
  • Template optimization: Reducing render overhead by caching complex transformations

Practical Implementation Example

The following example demonstrates both patterns in a <script setup> component:

<script setup lang="ts">
import { ref, computed } from 'vue'

const count = ref(1)

// Computed property: cached, reactive derivation
const double = computed(() => count.value * 2)

// Writable computed: two-way data flow
const half = computed({
  get: () => count.value / 2,
  set: (val) => (count.value = val * 2)
})

// Method: imperative action, no caching
function increment() {
  count.value++
}
</script>

<template>
  <p>Count: {{ count }}</p>
  <p>Double (computed): {{ double }}</p>
  <input v-model.number="half" type="number" placeholder="Half value" />
  <button @click="increment">Increment via method</button>
</template>

In this implementation, double creates a ComputedRefImpl instance that tracks count as a dependency, while increment is bound to the instance context and executes only when the button triggers it.

Summary

  • Methods are bound functions stored in the component context (ctx) via methodHandler.bind(publicThis), executing on every call without caching or dependency tracking.
  • Computed properties are ComputedRefImpl instances created by the computed API, offering reactive caching through dependency tracking and refreshComputed logic.
  • Use methods for actions, event handlers, and side effects that must run on demand.
  • Use computed properties for deriving reactive state, optimizing expensive calculations, and ensuring efficient template updates.

Frequently Asked Questions

Are computed properties cached in Vue?

Yes. According to the source code in packages/reactivity/src/computed.ts, computed properties use ComputedRefImpl to cache results. The getter only re-executes when tracked dependencies change; otherwise, it returns the cached value immediately.

Can I pass arguments to computed properties?

No. Computed properties are accessed as values, not functions, so they cannot accept runtime arguments. If you need parameterized logic, use a method instead, or create a computed property that returns a function (though this loses caching benefits for the inner function).

When should I use a method instead of a computed property?

Use a method when performing actions that change state, handling events, or executing logic that requires arguments. Methods run on every invocation and are ideal for side effects. Use a computed property only when deriving a value from existing reactive data without side effects.

Do methods and computed properties both have access to this?

Yes. Both are bound to the component instance during initialization. Methods are bound via methodHandler.bind(publicThis) in componentOptions.ts, while computed getters are bound via getter.bind(publicThis, publicThis). However, in Composition API with <script setup>, you typically access reactive refs directly rather than through this.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →