Skip to main content

What are composable functions?

Composable functions (or composition functions) are reusable functions that use the Composition API (ref, reactive, computed, watch, onMounted, etc.) and let you extract repeating logic out of components.

In simpler terms:

A composable is your own "hook" in Vue, the equivalent of React Hooks. It holds logic that can easily be reused across different components.


Example of a simple composable function

Let's create a function that implements a counter:

js
// useCounter.js import { ref } from 'vue' export function useCounter() { const count = ref(0) const inc = () => count.value++ const dec = () => count.value-- return { count, inc, dec } }

Now it can be used in any component:

vue
<script setup> import { useCounter } from './useCounter' const { count, inc, dec } = useCounter() </script> <template> <button @click="dec">-</button> {{ count }} <button @click="inc">+</button> </template>

Why do you need composable functions?

1. Reusing logic

You can extract repeated code out of components.

2. Better than mixins

Mixins caused:

  • naming conflicts
  • implicit logic
  • hard-to-read code

Composables are explicit and predictable.

3. Clean architecture

Each composable function is a separate module.

4. Convenient to test

A composable can be tested like a regular JS function.

5. Flexibility

You can use lifecycle hooks:

js
onMounted(() => console.log('mounted inside composable'))

Example: useFetch()

A very popular composable:

js
import { ref } from 'vue' export function useFetch(url) { const data = ref(null) const loading = ref(true) const error = ref(null) fetch(url) .then(res => res.json()) .then(json => data.value = json) .catch(err => error.value = err) .finally(() => loading.value = false) return { data, loading, error } }

Usage:

vue
<script setup> import { useFetch } from './useFetch' const { data, loading } = useFetch('/api/users') </script> <template> <div v-if="loading">Loading...</div> <pre v-else>{{ data }}</pre> </template>

Composables can use lifecycle hooks

js
export function useMouse() { const x = ref(0) const y = ref(0) function update(e) { x.value = e.pageX y.value = e.pageY } onMounted(() => window.addEventListener('mousemove', update)) onUnmounted(() => window.removeEventListener('mousemove', update)) return { x, y } }

Rules for composable functions (like React hooks)

  1. Called only at the top level of setup() or other composables.
  2. Not called inside loops, conditions, or async blocks.
  3. Names are conventionally prefixed with use (useAuth, useForm, useFetch).
  4. Only the public part of the API is returned (hiding internal details).

Summary (ideal for an interview)

Composable functions are reusable functions built on the Composition API that encapsulate logic (reactivity, computed, watch, lifecycle hooks) and let you easily share it between components. They replace mixins, making code modular, readable, testable, and flexible.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.