Composables in Vue 3: Writing Clean and Reusable Logic

As applications grow, organizing logic becomes just as important as building features. Vue 3 introduced one of its most powerful improvementsโ€”the ๐—–๐—ผ๐—บ๐—ฝ๐—ผ๐˜€๐—ถ๐˜๐—ถ๐—ผ๐—ป ๐—”๐—ฃ๐—œ, and with it, the concept of ๐—ฐ๐—ผ๐—บ๐—ฝ๐—ผ๐˜€๐—ฎ๐—ฏ๐—น๐—ฒ๐˜€. Composables let you extract logic out of components and reuse it anywhere in your app. The result? Cleaner components, reusable logic, and a far more scalable architecture.

Letโ€™s take a deep dive into how composables work and why theyโ€™ve become essential in modern Vue development.

๐—ช๐—ต๐—ฎ๐˜ ๐—”๐—ฟ๐—ฒ ๐—–๐—ผ๐—บ๐—ฝ๐—ผ๐˜€๐—ฎ๐—ฏ๐—น๐—ฒ๐˜€?

A ๐—ฐ๐—ผ๐—บ๐—ฝ๐—ผ๐˜€๐—ฎ๐—ฏ๐—น๐—ฒ๐˜€ is simply a JavaScript function that uses Vueโ€™s reactive features (ref, reactive, computed, watch, etc.) and returns logic you can reuse in multiple components.

They typically follow the naming convention:
๐˜‚๐˜€๐—ฒ๐—ฆ๐—ผ๐—บ๐—ฒ๐˜๐—ต๐—ถ๐—ป๐—ด() โ€” e.g., useAuth(), useFetch(), useCounter().

๐—ช๐—ต๐˜† ๐—จ๐˜€๐—ฒ ๐—–๐—ผ๐—บ๐—ฝ๐—ผ๐˜€๐—ฎ๐—ฏ๐—น๐—ฒ๐˜€?

โœ” ๐—–๐—น๐—ฒ๐—ฎ๐—ป๐—ฒ๐—ฟ ๐—–๐—ผ๐—บ๐—ฝ๐—ผ๐—ป๐—ฒ๐—ป๐˜๐˜€

Business logic moves out of the component, leaving your script section simple and focused.

โœ” ๐—›๐—ถ๐—ด๐—ต๐—น๐˜† ๐—ฅ๐—ฒ๐˜‚๐˜€๐—ฎ๐—ฏ๐—น๐—ฒ ๐—Ÿ๐—ผ๐—ด๐—ถ๐—ฐ

Anything that multiple components shareโ€”form validators, API calls, stateโ€”can be centralized.

โœ” ๐—•๐—ฒ๐˜๐˜๐—ฒ๐—ฟ ๐—ข๐—ฟ๐—ด๐—ฎ๐—ป๐—ถ๐˜‡๐—ฎ๐˜๐—ถ๐—ผ๐—ป

You can structure your project by domain (auth, user, cart, UI behavior) rather than cramming everything in components.

โœ” ๐—˜๐—ฎ๐˜€๐—ถ๐—ฒ๐—ฟ ๐—ง๐—ฒ๐˜€๐˜๐—ถ๐—ป๐—ด

Composables are pure functions, making them easy to test in isolation.

๐—•๐—ฎ๐˜€๐—ถ๐—ฐ ๐—˜๐˜…๐—ฎ๐—บ๐—ฝ๐—น๐—ฒ: ๐—” ๐—ฆ๐—ถ๐—บ๐—ฝ๐—น๐—ฒ ๐—–๐—ผ๐˜‚๐—ป๐˜๐—ฒ๐—ฟ ๐—–๐—ผ๐—บ๐—ฝ๐—ผ๐˜€๐—ฎ๐—ฏ๐—น๐—ฒ

๐˜‚๐˜€๐—ฒ๐—–๐—ผ๐˜‚๐—ป๐˜๐—ฒ๐—ฟ.๐—ท๐˜€

import { ref } from \'vue\';

export function useCounter() {
  const count = ref(0);

  const increment = () => count.value++;
  const decrement = () => count.value--;

  return { count, increment, decrement };
}

๐—จ๐˜€๐—ถ๐—ป๐—ด ๐—ถ๐˜ ๐—ถ๐—ป๐˜€๐—ถ๐—ฑ๐—ฒ ๐—ฎ ๐—ฐ๐—ผ๐—บ๐—ฝ๐—ผ๐—ป๐—ฒ๐—ป๐˜:

<script setup>
import { useCounter } from \'@/composables/useCounter\';
const { count, increment, decrement } = useCounter();
</script>

This keeps logic reusable and clean.

๐—•๐˜‚๐—ถ๐—น๐—ฑ๐—ถ๐—ป๐—ด ๐— ๐—ผ๐—ฟ๐—ฒ ๐—ฃ๐—ผ๐˜„๐—ฒ๐—ฟ๐—ณ๐˜‚๐—น ๐—–๐—ผ๐—บ๐—ฝ๐—ผ๐˜€๐—ฎ๐—ฏ๐—น๐—ฒ๐˜€

Composables can contain:

  • API calls
  • Form validation
  • Real-time listeners
  • LocalStorage interactions
  • Business rules
  • Reusable animations
  • Permission checks

Example: ๐˜‚๐˜€๐—ฒ๐—™๐—ฒ๐˜๐—ฐ๐—ต.๐—ท๐˜€

import { ref } from \'vue\';

export function useFetch(url) {
  const data = ref(null);
  const loading = ref(true);

  const load = async () => {
    loading.value = true;
    data.value = await fetch(url).then(res => res.json());
    loading.value = false;
  };

  load();
  return { data, loading, reload: load };
}

Now any component can fetch data without duplicating logic.

๐—•๐—ฒ๐˜€๐˜ ๐—ฃ๐—ฟ๐—ฎ๐—ฐ๐˜๐—ถ๐—ฐ๐—ฒ๐˜€ ๐—ณ๐—ผ๐—ฟ ๐—–๐—ผ๐—บ๐—ฝ๐—ผ๐˜€๐—ฎ๐—ฏ๐—น๐—ฒ๐˜€

๐Ÿญ. ๐—ก๐—ฎ๐—บ๐—ฒ ๐—–๐—น๐—ฒ๐—ฎ๐—ฟ๐—น๐˜†

useCart, useAuth, useDarkMode โ€” the name should describe the logicโ€™s purpose.

๐Ÿฎ. ๐—ž๐—ฒ๐—ฒ๐—ฝ ๐—ง๐—ต๐—ฒ๐—บ ๐—™๐—ผ๐—ฐ๐˜‚๐˜€๐—ฒ๐—ฑ

Each composable should do one job, not everything.

๐Ÿฏ. ๐—ข๐—ฟ๐—ด๐—ฎ๐—ป๐—ถ๐˜‡๐—ฒ ๐—ฏ๐˜† ๐——๐—ผ๐—บ๐—ฎ๐—ถ๐—ป

Create folders like:

/composables/auth
/composables/user
/composables/api

๐Ÿฐ. ๐—ฅ๐—ฒ๐˜๐˜‚๐—ฟ๐—ป ๐—ข๐—ป๐—น๐˜† ๐—ช๐—ต๐—ฎ๐˜โ€™๐˜€ ๐—ก๐—ฒ๐—ฒ๐—ฑ๐—ฒ๐—ฑ

Donโ€™t overload components with unnecessary reactive values.

๐Ÿฑ. ๐——๐—ผ๐—ฐ๐˜‚๐—บ๐—ฒ๐—ป๐˜ ๐—ฌ๐—ผ๐˜‚๐—ฟ ๐—–๐—ผ๐—บ๐—ฝ๐—ผ๐˜€๐—ฎ๐—ฏ๐—น๐—ฒ๐˜€

If working in a team, simple comments help others understand whatโ€™s inside.

๐—™๐—ถ๐—ป๐—ฎ๐—น ๐—ง๐—ต๐—ผ๐˜‚๐—ด๐—ต๐˜๐˜€

Composables are a game changer in Vue 3. They help you write cleaner code, reduce duplication, improve testing, and scale your architecture effortlessly. Once you start using composables, youโ€™ll find your components become shorter, clearer, and far easier to maintain.

If you are looking for any services related to Website Development, App Development, Digital Marketing and SEO, just email us at nchouksey@manifestinfotech.com

#Vuejs #Vue3 #Composables #CompositionAPI #ReusableLogic #WebDevelopment #JavaScript #FrontendDevelopment #VueTips #CleanCode #VueEcosystem #ModernVue #JSDeveloper #CodeReuse #WebAppDevelopment #DeveloperTips #ScalableArchitecture #VueCommunity #CodingBestPractices #ViteJs