useCounter: A Simple Composable
count ref, increment/decrement functions, reset, exposing only what's needed.
useCounter: A Simple Composable is a free Vue Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Vue Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Building useCounter
We will write a small but complete composable: useCounter. It manages a number and exposes methods to change it - a perfect first composable.
Accepting an Initial Value
Give the function an initial parameter with a default so callers can start the counter anywhere.
function useCounter(initial = 0) {
// ...
}The Internal count Ref
Inside, create a ref for the count, seeded with the initial value. This is the reactive state the composable owns.
import { ref } from "vue";
function useCounter(initial = 0) {
const count = ref(initial);
}The increment Function
Define a function that mutates the ref. Because count is reactive, every consumer updates automatically.
function increment() {
count.value++;
}decrement and reset
Add the complementary actions. reset uses the original initial captured in the closure.
function decrement() {
count.value--;
}
function reset() {
count.value = initial;
}Returning the API
Return an object with the reactive state and all methods. This is the composable public interface.
return { count, increment, decrement, reset };The Full Composable
Putting it together, the whole thing is compact and reusable across any component.
import { ref } from "vue";
export function useCounter(initial = 0) {
const count = ref(initial);
const increment = () => count.value++;
const decrement = () => count.value--;
const reset = () => count.value = initial;
return { count, increment, decrement, reset };
}Using It in a Component
Call it in <script setup> and destructure. The template can use count directly (auto-unwrapped) and bind the methods.
const { count, increment, decrement, reset } = useCounter(10);In the Template
Wire the methods to buttons. Each click mutates the shared ref and the view updates.
<button @click="decrement">-</button>
<span>{{ count }}</span>
<button @click="increment">+</button>Independent Instances
Each call to useCounter creates its own count ref. Two components calling it get separate, isolated counters.
const a = useCounter(); // own count
const b = useCounter(100); // own countAdding Computed Extras
You can enrich the composable with derived state, like an isZero computed, returned alongside the rest.
import { computed } from "vue";
const isZero = computed(() => count.value === 0);
// add to return: { count, isZero, increment, ... }Quick Check
Why does each call to useCounter get its own state?
Recap
You built useCounter(initial): an internal count ref, increment/decrement/reset functions, and a returned object exposing reactive state plus methods. Each call yields an independent instance.
Frequently asked questions
Is the “useCounter: A Simple Composable” lesson free?
Yes — the full text of “useCounter: A Simple Composable” is free to read here on the web, and the Vue Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Vue Academy course, upgrade to CoddyKit PRO.
What will I learn in “useCounter: A Simple Composable”?
count ref, increment/decrement functions, reset, exposing only what's needed. You practise Vue Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Vue Academy?
No prior experience is required. Vue Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “useCounter: A Simple Composable” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Vue Academy lesson?
Yes. Every Vue Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- What Makes a Good Composable
- useCounter: A Simple Composable
- useFetch: Async Data Composable
- VueUse: The Composable Library