0Pricing
Vue Academy · Lesson

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 count

Adding 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

  1. What Makes a Good Composable
  2. useCounter: A Simple Composable
  3. useFetch: Async Data Composable
  4. VueUse: The Composable Library
← Back to Vue Academy