SkillByAIOpen interactive version →

Lesson 10 / 25

Composables

Reusable stateful logic in useX functions.

Functions that use the Composition API

A composable is a function that uses Vue's reactivity and lifecycle APIs to encapsulate stateful logic, conventionally named useSomething. It returns refs (rather than a reactive object) so callers can destructure the result without losing reactivity. Each call creates independent state, unless you deliberately declare state outside the function to share it. Call composables synchronously at the top of <script setup> so their lifecycle hooks and watchers are tied to the current component. Accepting refs or getters as arguments, normalised with toValue() (Vue 3.3+), makes them flexible. The community library VueUse provides many ready-made composables.

Reusing logic, not just markup

Composables, lifecycle hooks and provide/inject organise logic across components.

Figure 4.1 — Composables, lifecycle and dependency injection.

A useMouse composable

State, lifecycle and cleanup in one function.

// composables/useMouse.js
import { ref, onMounted, onUnmounted } from 'vue'

export function useMouse() {
  const x = ref(0)
  const y = ref(0)

  function update(event) {
    x.value = event.pageX
    y.value = event.pageY
  }

  onMounted(() => window.addEventListener('mousemove', update))
  onUnmounted(() => window.removeEventListener('mousemove', update))

  return { x, y }
}

// In a component:
// <script setup>
// import { useMouse } from '@/composables/useMouse'
// const { x, y } = useMouse()
// </script>
// <template>Mouse at {{ x }}, {{ y }}</template>

A recipe card

A composable is a recipe card: each kitchen (component) that follows it cooks its own fresh dish (state), but the steps are written once.

Quick check: Why do composables usually return an object of refs rather than a reactive object?

  • So callers can destructure the result and keep reactivity
  • Refs use less memory
  • Reactive objects cannot be returned from functions
  • Templates cannot read reactive objects
Answer

So callers can destructure the result and keep reactivity — Destructuring a reactive object loses reactivity.