Vue 컴포저블 함수 구현 및 사용 방법

컴포저블 함수 (Composable)

반응형 상태 관리 로직을 캡슐화하여, 여러 컴포넌트에서 재사용할 수 있는 함수형 모듈입니다.
axios로 서버 API 호출하는 로직도 컴포저블 함수로 만들 수 있습니다.

컴포저블 함수 정의 방법

import { ref } from 'vue';

// 상태 변수는 모듈 범위에 정의하거나, 상태 관리 스토어 Pinia 사용 필요
// 함수 범위에 정의하면 함수를 호출하는 각 컴포넌트에서 변수가 생성되기 때문에 정상 동작 X
const data변수명1 = ref([]);

export function use컴포저블함수명() {

  // 상태 변경 함수 정의
  const 함수명1 = (파라미터1, 파라미터2) => {
    data변수명1.value.push({ 파라미터1, 파라미터2 });
  }

  return {
    data변수명1,
    함수명1,
  }
}

src/composables 폴더 안에 컴포저블 함수를 정의합니다.
컴포저블 함수 내 반응형 상태 정의 시 reactive 대신 ref 또는 computed 사용이 권장됩니다.
반환한 reactive 값을 구조분해 할당으로 재할당하면, 반응성이 사라지기 때문입니다.

Pinia 스토어 사용하여 컴포저블 함수 정의 예시

import { use데이터분류명Store } from "@/stores/데이터분류명Store.js";

const 데이터분류명Store = use데이터분류명Store();
const { data변수명1}  = storeToRefs(데이터분류명Store);

export function use컴포저블함수명() {

  // 상태 변경 함수 정의
  const 함수명1 = (파라미터1, 파라미터2) => {
    데이터분류명Store.actions함수명();
  }

  return {
    data변수명1,
    함수명1,
  }
}

서버 API 호출 컴포저블 함수 정의 예시

import axios from 'axios';
import { ref, unref, watchEffect } from 'vue';

// 전역 기본 URL 설정
axios.defaults.baseURL = import.meta.env.VITE_APP_API_URL;

// 기본 config 설정
const defaultConfig = {
  method: 'get',
}

export default function usePosts(url, config = {}, callbacks = {}) {
  const posts = ref([]);
  const loading = ref(false);
  const error = ref(null);

  const { params } = config;

  const { onSuccess, onError } = callbacks;

  // .then() 체이닝 방식 비동기 호출 예시
  const getPosts = () => {
    posts.value = [];
    error.value = null;
    loading.value = true;

    axios.get(url, {
      ...defaultConfig,
      ...config, // config 파라미터에 같은 속성이 있으면 덮어씌움
      params: unref(params),
    })
    .then(response => {
      posts.value = response.data;

      // 성공 시 콜백 함수가 있으면 실행
      if (onSuccess) {
        onSuccess(response);
      }
    })
    .catch(err => {
      error.value = err;

      // 실패 시 콜백 함수가 있으면 실행
      if (onError) {
        onError(err);
      }
    })
    .finally(() => {
      loading.value = false;
    });
  }

  // params가 반응형 상태인 경우
  if (isRef(params)) {
    // 내부에서 참조된 params 반응형 상태 값 변경 시마다 getPosts 자동 실행
    watchEffect(getPosts);
  } else {
    // params가 일반 변수인 경우
    getPosts();
  }

  return {
    posts,
    loading,
    error,
    getPosts,
  };
}

게시글 조회 컴포저블 함수 src/composables/usePosts.js 파일 예시입니다.
반환한 loading, error 반응형 상태로 UI를 변경할 수 있습니다.

// 서버 요청 파라미터 정의
const params = ref({
  _sort: 'createdAt',
  _order: 'desc',
  _page: 1,
  _limit: 3,
  title_like: '',
});

// 컴포저블 훅 호출
const { posts, error, loading, getPosts } = usePosts('/posts', { method: 'get', params }, {
  // 콜백 함수 정의
  onSuccess: () => {
    // 성공 시 실행 로직 작성
  },
  onError: (err) => {
    // 실패 시 실행 로직 작성
  },
});

// 서버 API 호출 및 데이터 업데이트 요청 (수동)
// params가 바뀌면 자동 호출되어서 수동 요청 필요 X
getPosts();

위와 같이, 컴포저블 훅 호출 후 반응형 상태와 함수를 받아 사용할 수 있습니다.

컴포저블 함수 사용 방법

<script setup>
import { use컴포저블함수명 } from '@/composables/컴포저블함수파일명';

const { data변수명1, 함수명1 } = use컴포저블함수명();

함수명1();
</script>

위와 같이, 컴포넌트 script에서 컴포저블 함수 import 후 사용할 수 있습니다.