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. This is lesson 2 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Vue Academy learning path, and your progress syncs across the web and the CoddyKit app. The Vue Academy course includes 4 lessons in total.
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.
Learn HTML with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 42
- Lessons
- 156
Frequently Asked Questions
Is the “useCounter: A Simple Composable” lesson free?
Yes — any 3 lessons of the Vue Academy learning path, including “useCounter: A Simple Composable”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Vue Academy course includes 4 lessons in total.
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, so you can start here or from the beginning and move at your own pace. This is lesson 2 of 4.
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