개발자 9Diin의 개발일기

Vue.js 컴포지션 API란 무엇인가? (feat. 코드설명) 본문

2021-2023

Vue.js 컴포지션 API란 무엇인가? (feat. 코드설명)

9Diin 2022. 7. 5. 19:50
반응형

https://youtu.be/XwMBu6yrlUo

📌 Reusability & Composition

이번 포스팅은 'Vue.js 프로젝트 투입 일주일 전' 도서를 참고했습니다.

 

✅ Composition API

컴포지션 API는 컴포넌트 내에서 사용하는 특정 기능을 갖는 코드를 유연하게 구성하여 사용할 수 있도록 Vue3 버전에 추가된 함수 기반의 API이다. 컴포넌트 API가 생긴 이유는 Vue는 프로젝트 규모가 커질수록 관리하기 힘들다. 는 단점이 있어서 컴포넌트의 계층구조가 복잡할수록 코드에 대한 추적 및 관리가 어려웠다고 한다. 그래서 생겼다고 한다.

 

그래서 컴포지션 API를 이용하면, setup( )이라는 메서드 안에서 한 덩어리로 코드를 구현할 수 있기에 코드에 대한 관리가 훨씬 쉬워진다고 한다. 즉, 컴포지션 API는 그동안 Vue가 가지고 있던 단점을 보완하기 위해 추가된 핵심기능이라 한다. 나도 여러 인터넷 강의를 보면서 사용은 해봤지만, 정작 내가 만든 프로젝트에서 setup( )을 어떻게 활용하여 작성해야 할지 아직 감이 안 온다.

 

컴포지션 API 역시 API라는 이름을 붙인 것처럼, 특정 기능을 갖는 함수를 정의하고 API처럼 사용할 수 있게 해주는 것이다. 결국 궁극적인 목적인 코드에 대한 재활용성을 높이고, 코드의 가독성을 높이기 위해 추가된 기능이다.

 

✅ Setup

Setup( ) 은 컴포지션 API를 구현하는 곳이다.

 

Setup 사용 전 코드

<template>
  <div>
    <h2>Calculator</h2>
    <div>
      <input type="text" v-model="num1" @keyup="plusNumbers" />
      <span> + </span>
      <input type="text" v-model="num2" @keyup="plusNumbers" />
      <span> = </span>
      <span>{{ result }}</span>
    </div>
  </div>
</template>

<script>
export default {
  name: "Calculator",
  data() {
    return {
      num1: 0,
      num2: 0,
      result: 0,
    };
  },
  methods: {
    plusNumbers() {
      this.result = parseInt(this.num1) + parseInt(this.num2);
    },
  },
};
</script>

 

Setup 사용 후 코드

<template>
  <div>
    <h2>Calculator</h2>
    <div>
      <input type="text" v-model="num1" @keyup="plusNumbers" />
      <span> + </span>
      <input type="text" v-model="num2" @keyup="plusNumbers" />
      <span> = </span>
      <span>{{ state.result }}</span>
    </div>
  </div>
</template>

<script>
import { reactive } from "vue";

export default {
  name: "Calculator",
  setup() {
    let state = reactive({
      // reactive를 이용해서 num1, num2, result를 실시간 변경사항에 대한 반응형 적용
      num1: 0,
      num2: 0,
      result: 0,
    });

    function plusNumbers() {
      state.result = parseInt(this.num1) + parseInt(this.num2);
    }
    return {
      // reactive로 선언된 state와 plusNumbers 함수를 반환함으로써
      // 기존 data, methods 옵션처럼 사용이 가능해짐
      state,
      plusNumbers,
    };
  },
};
</script>

 

computed를 활용하여 코드를 보다 깔끔하게 변경

 

<template>
  <div>
    <h2>Calculator</h2>
    <div>
      <input type="text" v-model="num1" />
      <span> + </span>
      <input type="text" v-model="num2" />
      <span> = </span>
      <span>{{ state.result }}</span>
    </div>
  </div>
</template>

<script>
import { reactive, computed } from "vue"; // computed 추가

export default {
  name: "Calculator",
  setup() {
    let state = reactive({
      // reactive를 이용해서 num1, num2, result를 실시간 변경사항에 대한 반응형 적용
      num1: 0,
      num2: 0,
      result: computed(() => {
        // computed를 이용해서 num1, num2가 변경이 일어나면 즉시 result로 더한 값을 반환
        parseInt(this.num1) + parseInt(this.num2);
      }),
    });
    return {
      state,
    };
  },
};
</script>

 

reactive와 computed를 이용하니 input type = text에 바인딩했던 keyup 이벤트를 없앨 수 있고, 코드가 훨씬 깔끔해졌다. 그러나 위 코드는 현재 컴포넌트에서만 사용 가능하다.

 

✅ 외부에서 Composition API 활용하기

일단 Setup에 작성된 코드를 분리하여 별도의 function으로 작성하자.

 

<template>
  <div>
    <h2>Calculator</h2>
    <div>
      <input type="text" v-model="num1" />
      <span> + </span>
      <input type="text" v-model="num2" />
      <span> = </span>
      <span>{{ result }}</span>
    </div>
  </div>
</template>

<script>
import { reactive, computed, toRefs } from "vue"; // toRefs 추가

function plusCalculator() {
  let state = reactive({
    num1: 0,
    num2: 0,
    result: computed(
      () =>
        // computed를 이용해서 num1, num2가 변경이 일어나면 즉시 result로 더한 값을 반환
        parseInt(this.num1) + parseInt(this.num2)
    ),
  });
  // 반응형으로 선언된 num1, num2, result가 외부 function 에서 정상적으로 동작하기 위해서는 toRefs를 사용해야한다.
  return toRefs(state);
}

export default {
  name: "Calculator",
  setup() {
    let { num1, num2, result } = plusCalculator(); // 외부 function
    return {
      num1,
      num2,
      result,
    };
  },
};
</script>

 

외부 function에서 반응형 변수를 사용하기 위해서 toRefs가 추가되었다.

 

컴포넌트 안에서는 v-model 디렉티브를 통해 바인딩된 변수가 사용자의 입력값이 바뀔 대마다 반응형으로 처리가 되었지만, 함수를 컴포넌트 밖으로 빼면 사용자가 입력한 값에 대한 반응형 처리가 불가능해진다. 그래서 toRefs를 사용하여 컴포넌트 밖에서도 반응형 처리가 가능하도록 할 수 있다.

 

Composition API 활용 예제 1

Composition API 활용 예제 2

Composition API 활용 예제 3

 

위 Composition API 활용 예제를 보았을 때, 보다 깊이 있게 설명을 해보자면, Composition API 방식으로 코드를 작성하기 전(왼쪽) data( ) 안에서 return으로 받는 데이터를 각각 계산된 데이터인 Computed와 Watch로 감시하고 있다. 이를 Composition API 형식으로 코드를 재작성하려면, setup( )이라는 메서드를 활용해야 한다. 그 다음에 각각 변수를 할당하여 data( ) 부분의 데이터는 ref로 참조받고, 함수는 computed로 참조 받아 값을 변수의 .value로 받는다. 그리고 각각 변수들을 return 시켜준다. 

 

반응형