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:
// 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:
<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:
onMounted(() => console.log('mounted inside composable'))Example: useFetch()
A very popular composable:
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:
<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
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)
- Called only at the top level of
setup()or other composables. - Not called inside loops, conditions, or async blocks.
- Names are conventionally prefixed with
use(useAuth,useForm,useFetch). - 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 readyA concise answer to help you respond confidently on this topic during an interview.