Chapter 10: Vue Methods
Vue Methods — like we’re sitting together in a Hyderabad café, laptop open, building something fun step by step 😄
In Vue, “methods” are simply the functions you define to handle user interactions, business logic, or any action that needs to be triggered (clicks, form submits, timers, API calls, etc.).
But here’s the important thing in 2026:
Vue gives you two main ways to write these methods, and which one you use depends on whether you’re using the Options API (classic style) or the Composition API (modern, recommended style).
- Options API → methods live in a methods: { } object
- Composition API (especially with <script setup>) → methods are just normal JavaScript functions declared at the top level
The Composition API + <script setup> is now the default recommendation for almost all new Vue 3 code in 2025–2026. The Options API is still fully supported (great for legacy code or very small components), but most tutorials, jobs, and large apps have moved to Composition.
I’ll teach you both so you understand old code, new code, and can choose wisely.
1. Methods in Options API (Classic Vue 2 / early Vue 3 style)
This is how methods looked in most Vue 2 apps and many Vue 3 apps that haven’t migrated yet.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
<template> <div class="counter-box"> <p>Count: {{ count }}</p> <button @click="increment">+1</button> <button @click="decrement">-1</button> <button @click="reset">Reset to 0</button> <p v-if="count >= 10">Wow, you're on fire! 🔥</p> </div> </template> <script> export default { data() { return { count: 0 } }, methods: { // ← all methods go here increment() { this.count++ this.logAction('incremented') }, decrement() { this.count-- this.logAction('decremented') }, reset() { this.count = 0 alert('Reset done!') }, logAction(action) { // helper method console.log(`Count was ${action}. New value: ${this.count}`) } } } </script> <style scoped> .counter-box { text-align: center; padding: 2rem; } button { margin: 0.5rem; padding: 0.8rem 1.5rem; } </style> |
Key characteristics:
- All methods inside methods: { }
- Access data with this.count, this.logAction(…)
- this refers to the component instance
- Good for: small components, people coming from Vue 2, quick prototypes
2. Methods in Composition API + <script setup> (Modern 2026 way – recommended!)
This is how almost everyone writes Vue components today.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
<template> <div class="counter-box"> <p>Count: {{ count }}</p> <button @click="increment">+1</button> <button @click="decrement">-1</button> <button @click="reset">Reset to 0</button> <p v-if="count >= 10">Wow, you're on fire! 🔥</p> </div> </template> <script setup> import { ref } from 'vue' const count = ref(0) // ← Methods are just plain functions! function increment() { count.value++ logAction('incremented') } function decrement() { count.value-- logAction('decremented') } function reset() { count.value = 0 alert('Reset done!') } // Helper function (also a "method") function logAction(action) { console.log(`Count was ${action}. New value: {count.value}`) } </script> <style scoped> /* same as above */ </style> |
Key differences & advantages:
- No methods: { } object
- No this at all! → much cleaner, less confusing
- Functions are declared normally with function name() or const name = () => { }
- Everything top-level in <script setup> is automatically available in <template>
- Easier to extract logic into composables (reusable functions)
3. Methods with Parameters & Event Object
Modern style example:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<template> <button @click="greet('Rahul', $event)">Say Hi</button> <input @keyup.enter="search($event.target.value)" placeholder="Type + Enter" /> </template> <script setup> function greet(name, event) { alert(`Namaste ${name} from Hyderabad! 🌶️`) console.log('Click position:', event.clientX, event.clientY) } function search(query) { console.log('Searching for:', query) // fetch(`/api/search?q=${query}`) } </script> |
4. When Methods Become Computed or Watchers (common confusion)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<script setup> import { ref, computed } from 'vue' const count = ref(5) // Method (action) function doubleIt() { count.value *= 2 } // Computed (derived value – not a method!) const doubled = computed(() => count.value * 2) // Don't do this as method if you want reactive auto-update // const doubledWrong = () => count.value * 2 ← use computed instead! </script> <template> <p>Doubled (computed): {{ doubled }}</p> <button @click="doubleIt">Double Count</button> </template> |
Rule of thumb 2026:
- Want to do something (change state, call API, show alert) → method (plain function)
- Want a derived value that auto-updates → computed()
- Want to react to change → watch() or watchEffect()
Quick Comparison Table – Methods in 2026
| Aspect | Options API | Composition API + <script setup> | Winner in 2026 |
|---|---|---|---|
| Declaration | methods: { increment() { … } } | function increment() { … } | Composition |
| Accessing state | this.count++ | count.value++ | Composition (no this) |
| Boilerplate | More (export default, methods block) | Minimal | Composition |
| Reusability | Harder to extract logic | Easy → composables | Composition |
| TypeScript support | Okay | Excellent | Composition |
| Still used? | Legacy code, small widgets | New projects, large apps | — |
Real-World Advice from Hyderabad 2026
- New project? → Use <script setup> + plain functions (methods)
- Maintaining old Vue 2 / early Vue 3 code? → Learn Options API methods: { }
- Large team? → Composition makes code easier to split, test, reuse
- Want to share logic between components? → Turn methods into composables
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// useCounter.js (composable) import { ref } from 'vue' export function useCounter(initial = 0) { const count = ref(initial) function increment() { count.value++ } function decrement() { count.value-- } function reset() { count.value = initial } return { count, increment, decrement, reset } } |
|
0 1 2 3 4 5 6 7 8 9 |
<script setup> import { useCounter } from '@/composables/useCounter' const { count, increment, reset } = useCounter(10) </script> |
Practice challenge:
- Build a form with submit method
- Add validation method
- Create a reset method
- Extract counter logic to a composable
Any part unclear? Want full example with API call method? Or how to type methods in TypeScript? Or difference when using arrow functions?
Just tell me — we’ll keep building your Vue skills step by step 🚀
Happy coding from Webliance, Hyderabad! 💙
