본문 바로가기

카테고리 없음

[Vue.js] 컴포저블(Composable)이란 무엇인가?

728x90

[Vue.js] 컴포저블(Composable)을 배우며 느낀 점

Vue 3에서 Composition API를 쓰다 보면 자연스럽게 접하게 되는 개념이 있다. 바로 컴포저블(Composable)이라는 것이다.

처음에는 단순히 setup() 안에서 로직을 작성하는 것만으로도 만족했는데, 컴포저블이라는 개념을 알게 되면서 코드 재사용과 유지보수 측면에서 큰 차이가 난다는 걸 배웠다.

컴포저블이란?

간단하게 말하자면, 반복적으로 사용하는 로직을 함수처럼 분리해서 가져다 쓰는 방식이다. React로 치면 custom hook과 매우 유사한 느낌이다.

예를 들어, 카운터 기능이 여러 컴포넌트에서 필요하다면 그 로직을 매번 setup() 안에 반복해서 작성할 필요 없이, 컴포저블로 하나 만들어두고 가져다 쓰면 된다.

예제 - useCounter

가장 많이 보는 기본 예제 중 하나. 나도 이걸 직접 구현해보면서 개념을 이해하게 됐다.

// composables/useCounter.js
import { ref } from 'vue'

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

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

  return {
    count,
    increment,
    decrement
  }
}

컴포넌트 안에서는 이렇게 사용하면 된다:

<script setup>
import { useCounter } from '@/composables/useCounter'

const { count, increment, decrement } = useCounter(5)
</script>

<template>
  <div>
    <p>카운트: {{ count }}</p>
    <button @click="increment">증가</button>
    <button @click="decrement">감소</button>
  </div>
</template>

정말 직관적이고, 컴포넌트에 꼭 필요한 데이터만 깔끔하게 쓰게 해주는 느낌이었다.

어떤 걸 컴포저블로 뽑으면 좋을까?

내가 느끼기엔 다음과 같은 상황일 때 컴포저블로 분리하면 좋았다.

  • 2개 이상의 컴포넌트에서 동일한 로직을 사용
  • API 호출 로직
  • 다크모드, 윈도우 사이즈 등 환경 상태 관리
  • 폼 validation, 입력값 처리

실전 예제 - useDarkMode

개인 프로젝트에서 실제로 다크모드를 적용하면서 만들었던 컴포저블이다. 문서 전체에 클래스를 토글하는 방식으로 구현했다.

// composables/useDarkMode.js
import { ref, watchEffect } from 'vue'

export function useDarkMode() {
  const isDark = ref(false)

  watchEffect(() => {
    document.documentElement.classList.toggle('dark', isDark.value)
  })

  return { isDark }
}

사용할 땐 이렇게 쓰면 된다:

<script setup>
import { useDarkMode } from '@/composables/useDarkMode'

const { isDark } = useDarkMode()
</script>

<template>
  <label>
    <input type="checkbox" v-model="isDark" /> 다크 모드
  </label>
</template>

마무리하며

Vue에서 컴포저블을 사용하면서 느낀 가장 큰 장점은 코드의 명확성과 재사용성이었다. 특히 프로젝트가 커질수록, 이런 구조적인 분리가 얼마나 중요한지 점점 체감하게 된다.

예전엔 mixin이나 이벤트 버스로 이런 걸 처리했다면, 이제는 useXXX 식으로 함수 하나 만들고 나눠쓰면 된다. 로직의 출처가 명확하고, 테스트도 편하고, 코드도 깔끔해졌다.

앞으로도 프로젝트를 하면서 자주 사용하게 될 것 같고, 더 다양한 패턴도 직접 만들어보며 익혀야겠다고 생각했다.

728x90
반응형