Explain how template method calls are executed during render, why they run again on every component re-render, the performance/correctness pitfalls (expensive work, unstable references, side effects), and when to prefer computed properties or precomputed data.
What happens when you call methods inside Vue templates?
Use guided tracks for structured prep, then practice company-specific question sets when you want targeted interview coverage.
Core idea
Anything you reference in a Vue template is evaluated during the component’s render. A method call in the template is just a function call inside the compiled render function. That means:
• The method runs on the initial render.
• The method runs again on every subsequent re-render of that component.
Vue will track reactive reads that happen inside the method (because it runs during render), but the result is not cached like a computed property.
Approach | How often it runs | Caching | Best for |
|---|---|---|---|
Method call in template: {{ format() }} | Every render of the component | No | Event-ish logic, cheap formatting, simple helpers |
Computed: {{ formatted }} | Only when its reactive deps change (then reused) | Yes (until invalidated) | Derived state, expensive transforms, stable references |
Inline expression: {{ a + b }} | Every render | No | Very small expressions only |
<script setup>
import { ref, computed } from 'vue';
const count = ref(0);
const theme = ref('light');
function expensiveFormat(n) {
// pretend heavy work
let s = '';
for (let i = 0; i < 50000; i++) s = String(n);
return `Count: ${s}`;
}
const formatted = computed(() => expensiveFormat(count.value));
</script>
<template>
<!-- Method: runs whenever this component re-renders (even if only theme changes) -->
<p>{{ expensiveFormat(count) }}</p>
<!-- Computed: recomputes only when count changes -->
<p>{{ formatted }}</p>
<button @click="count++">inc</button>
<button @click="theme = theme === 'light' ? 'dark' : 'light'">toggle theme</button>
</template>
Why this can hurt performance
A component can re-render for many reasons (any reactive dependency used in render changes). If you call a method in the template, it’s executed again even when the method’s “inputs” didn’t change. In lists, it’s worse: a method used inside v-for can run per item per render.
Pitfall | What you’ll see | Fix |
|---|---|---|
Expensive method in template | UI jank / slow typing / slow toggles | Move work into a computed, or precompute once (e.g., computed map / cached lookup) |
Method allocates new objects/arrays each render | Child components update unnecessarily (new prop reference each render) | Return stable references via computed, or compute once and reuse |
Method has side effects (mutates reactive state, logs, API calls) | Infinite update loops, warnings, repeated API calls | Keep template-called methods pure; do side effects in events/watchers |
Method depends on params (e.g., format(item)) | You can’t just “convert to computed” 1:1 | Precompute a derived structure (Map/object) via computed; or memoize by key |
When it’s OK to use a method in the template
• It’s cheap (simple string/number formatting).
• It’s pure (no state writes, no I/O).
• It doesn’t allocate large new structures on every call.
Rule of thumb: if you’d be annoyed seeing it run on every render in a profiler, make it a computed (or precomputed data) instead.