매일 업데이트
2023-09-01 03:30 8 min

더 나은 구성 요소 개발을 위해 Vue 3 Composition API로 마이그레이션

Vue의 개발자들이 Vue 2의 지원을 2023년 12월 31일부로 종료한다고 발표함에 따라, 개발자들은 Vue 3로의 전환을 적극적으로 고려해야 합니다.

이러한 전환과 함께, Vue 애플리케이션을 구축하는 데 있어 더욱 모듈화되고, 선언적이며, 타입 안전성을 높이는 접근 방식을 제공하는 기능인 컴포지션 API가 도입되었습니다.

컴포지션 API란 무엇인가?

컴포지션 API는 Options 객체를 사용하여 Vue 컴포넌트를 작성하는 기존 방식에서 패러다임을 전환한 것입니다. 이 새로운 개발 스타일은 더욱 선언적인 접근 방식을 채택하여, 구현 세부사항을 추상화하고 Vue 앱 구축 자체에 집중할 수 있도록 합니다.

컴포지션 API 개발의 동기

Vue 개발자들은 Options 객체를 활용하여 복잡한 웹 애플리케이션을 구축할 때 발생하는 어려움을 인지했습니다. 프로젝트 규모가 커질수록 컴포넌트의 논리 관리가 점차 어려워지고, 유지보수가 더욱 까다로워졌습니다. 특히 협업 환경에서는 더욱 그렇습니다.

기존의 Options 객체 방식은 컴포넌트의 속성이 많아지면서 코드를 이해하고 관리하기 어렵게 만들었습니다.

또한, 여러 컴포넌트에서 컴포넌트 로직을 재사용하는 과정이 번거로웠습니다. 다양한 라이프사이클 훅과 메소드 내에 분산된 로직은 컴포넌트의 전체 동작을 파악하는 데 복잡성을 더했습니다.

컴포지션 API의 이점

컴포지션 API는 Options API에 비해 몇 가지 뛰어난 장점을 제공합니다.

1. 성능 향상

Vue 3에는 프록시 기반 반응형 시스템이라는 새로운 렌더링 메커니즘이 도입되었습니다. 이 시스템은 메모리 사용량을 줄이고 반응성을 개선하여 전체적인 성능을 향상시킵니다. 새로운 반응형 시스템 덕분에 Vue 3는 더 크고 복잡한 컴포넌트 트리를 보다 효율적으로 처리할 수 있습니다.

2. 번들 크기 감소

최적화된 코드베이스와 트리 쉐이킹 기능 지원 덕분에 Vue 3는 Vue 2에 비해 번들 크기가 더 작습니다. 이러한 번들 크기 감소는 로딩 시간을 단축시키고 전반적인 성능을 향상시키는 데 기여합니다.

3. 개선된 코드 구성

컴포지션 API를 사용하면 컴포넌트 코드를 더 작고 재사용 가능한 함수 단위로 구성할 수 있습니다. 이는 특히 크고 복잡한 컴포넌트의 이해도와 유지보수성을 높이는 데 도움이 됩니다.

4. 컴포넌트 및 함수의 재사용성

컴포지션 함수는 다양한 컴포넌트에서 쉽게 재사용될 수 있어 코드 공유 및 재사용 가능한 함수 라이브러리 생성이 용이합니다.

5. 향상된 TypeScript 지원

컴포지션 API는 더욱 포괄적인 TypeScript 지원을 제공하여 개발 과정에서 더욱 정확한 타입 추론과 타입 관련 오류 식별을 용이하게 합니다.

Options 객체와 컴포지션 API 비교

이제 컴포지션 API의 기본 개념을 이해했으므로, 실제 사용 사례를 살펴보겠습니다. 컴포지션 API의 장점을 명확히 하기 위해 두 접근 방식의 주요 측면을 비교해 보겠습니다.

Vue 3의 반응형 데이터

반응형 데이터는 애플리케이션 데이터 변경 시 사용자 인터페이스가 자동으로 업데이트되도록 하는 Vue의 핵심 개념입니다.

Vue 2는 `Object.defineProperty` 메소드를 기반으로 하는 반응형 시스템에 의존하며, 모든 반응형 속성을 포함하는 `data` 객체를 사용합니다.

Vue 컴포넌트 내에서 `data` 옵션을 사용하여 데이터 속성을 정의하면, Vue는 새로운 ECMA 스크립트(ES6) 기능인 getter 및 setter를 사용하여 해당 데이터 객체의 각 속성을 자동으로 래핑합니다.

이러한 getter 및 setter는 속성 간의 종속성을 추적하고 속성이 수정될 때 UI를 업데이트합니다.

다음은 Options 객체를 사용하여 Vue 2에서 반응형 데이터를 생성하는 방법을 보여주는 예시입니다.

 <template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>

<script>
export default {
data() {
return {
count: 0,
};
},

methods: {
increment() {
this.count++;
},
},
};
</script>

위 코드 블록은 Vue 2에서 변수를 생성하는 방법을 보여줍니다. Vue는 `data` 객체 내에 정의된 변수를 자동으로 반응형으로 만듭니다. `count` 데이터 속성이 변경되면 애플리케이션 UI가 업데이트됩니다.

또한 `methods` 객체를 사용하여 컴포넌트 내부에서 사용되는 JavaScript 함수를 정의했습니다. 이 예시에서 코드 조각은 `count` 변수의 값을 1씩 증가시키는 `increment()` 메소드를 정의합니다.

Vue 2에서 함수를 메소드로 작성할 때는 `this` 키워드(`this.count++`)를 사용해야 합니다. `this` 키워드는 데이터 객체의 변수를 참조합니다. `this` 키워드를 생략하면 Vue가 컴포넌트를 마운트할 때 오류가 발생합니다.

Vue 3의 프록시 기반 반응형 시스템은 JavaScript 프록시를 사용하여 반응성을 구현함으로써 성능을 크게 향상시키고 반응형 종속성을 보다 효율적으로 처리할 수 있습니다.

Vue 3에서 반응형 데이터를 정의할 때는 `ref` 또는 `reactive` 함수를 사용합니다. `ref` 함수는 값에 대한 단일 반응형 참조를 생성하는 반면, `reactive` 함수는 여러 속성을 포함하는 반응형 객체를 생성합니다.

다음은 Vue 3의 `ref` 함수를 사용하여 반응형 데이터를 생성하는 방법의 예시입니다.

 <script setup>
import { ref } from 'vue';

const count = ref(0);

function increment() {
count.value++;
}
</script>

<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>

Vue 3에서 `ref()` 함수를 사용하려면 먼저 `vue` 패키지에서 해당 함수를 가져와야 합니다. `ref()` 함수는 변수에 대한 반응형 참조를 생성합니다.

위 코드 블록 예시에서는 `ref()` 함수를 사용하여 `count` 변수를 생성하고 초기 값을 0으로 설정합니다. `ref()` 함수는 `value` 속성을 가진 객체를 반환합니다. 이 `value` 속성은 실제 `count` 값을 저장합니다.

`@click` 지시어는 Vue에서 클릭 이벤트를 처리하는 데 사용됩니다.

스크립트 setup 블록 내부에는 컴포넌트에 필요한 기능을 정의합니다. Vue 3는 Vue 2에서 함수를 정의하는 데 사용되던 메소드 구문을 일반 JavaScript 함수로 대체했습니다.

이제 변수 이름에 `value` 메소드를 연결하여 `ref()` 함수로 정의한 반응형 변수에 접근할 수 있습니다. 예를 들어, 위 코드 블록은 `count.value`를 사용하여 `count` 변수의 값을 참조합니다.

Vue 3의 계산된 함수

계산된 함수는 반응형 데이터를 기반으로 파생된 값을 정의할 수 있는 또 다른 Vue 기능입니다. 계산된 속성은 해당 종속성이 변경될 때마다 자동으로 업데이트되므로 파생된 값이 항상 최신 상태로 유지됩니다.

Vue 2에서는 컴포넌트 내의 `computed` 옵션을 사용하여 계산된 동작을 정의합니다. 다음은 그 예시입니다.

 <template>
<div>
<p>Count: {{ count }}</p>
<p>Double Count: {{ doubleCount }}</p>
<button @click="incrementCount">Increment Count</button>
</div>
</template>

<script>
export default {
data() {
return {
count: 0
};
},
computed: {
doubleCount() {
return this.count * 2;
}
},
methods: {
incrementCount() {
this.count++;
}
}
};
</script>

위의 예시에서 `doubleCount` 계산 속성은 `count` 데이터 속성에 종속되어 있습니다. `count` 속성이 변경될 때마다 Vue는 `doubleCount` 속성을 다시 계산합니다.

Vue 3에서는 컴포지션 API 내에 계산된 함수를 사용하여 계산된 속성을 정의하는 새로운 방식을 도입했습니다. 그 예시는 다음과 같습니다.

 <script setup>
import { ref, computed } from 'vue';

const count = ref(0);
const doubleCount = computed(() => count.value * 2);

const incrementCount = () => {
count.value++;
};
</script>

<template>
<div>
<p>Count: {{ count }}</p>
<p>Double Count: {{ doubleCount }}</p>
<button @click="incrementCount">Increment Count</button>
</div>
</template>

계산된 함수를 사용하려면 먼저 `vue` 패키지에서 `computed` 함수를 가져와야 합니다.

위 코드 블록에서는 `computed` 함수를 사용하여 `doubleCount` 계산된 참조를 정의했습니다. Vue 3는 계산된 속성을 계산된 참조로 취급하여 반응형 변수에 대한 의존성을 강조합니다.

`computed` 함수는 반응형 데이터를 기반으로 파생된 값을 계산하는 getter 함수를 인수로 사용합니다. 이 예시에서 `doubleCount` 계산된 참조는 `count` 반응형 변수에 2를 곱한 값을 반환합니다.

컴포지션 API를 기반으로 작성된 코드 블록은 Options 객체로 작성된 코드 블록보다 가독성이 높고 간결합니다.

Vue에서 사용자 정의 지시어 생성 배우기

Vue 3 컴포지션 API는 Vue 컴포넌트에서 코드를 구성하고 재사용하는 강력하고 유연한 접근 방식을 제공합니다. 컴포지션 API를 사용하면 더욱 모듈화되고 유지보수가 용이한 Vue 애플리케이션을 구축할 수 있습니다.

Vue는 웹 앱 개발 과정에서 생산성을 극대화하기 위한 추가적인 기능도 제공합니다. Vue 애플리케이션의 여러 부분에서 특정 기능을 재사용하기 위해 사용자 정의 지시어를 생성하는 방법을 익힐 수 있습니다.

저자
Korea

기술 트렌드와 실용적인 팁을 전하는 लेखक입니다.