2025. 3. 12. 17:08ㆍVue
개요
- vue3 프로젝트를 하면서 vuex를 통해 관리하던 상태변경을 pinia를 이용해야했다.
- pinia 와 vuex의 차이점을 알고 사용해보기로 함
- 이에 앞서 이전 버전과 다른 vue3의 설계구조를 알아야 함
- Composition API vs Options API 의 차이
composition API란 무엇일까?
-> vue3에서 도입된 새로운 방식의 컴포넌트 설계 방법.
이전에는 options API(옵션 객체 data, methods, computed, etc.를 이용하여 구성) 를 사용해 컴포넌트를 작성.
composition API는 좀 더 유연하고 효율적인 코드를 작성할 수 있도록 해준다. 주요 개념은 **반응성(reactivity)**과 컴포넌트의 상태와 기능을 함수 기반으로 구성하는 것!
ex. options API를 이용한 컴포넌트 작성

** Composition API vs Options API 의 특징 정리
| 특징 | Composition API | Options API |
| 구성방식 | 함수 기반으로 상태와 로직을 분리하여 구성 | 옵션 객체 (data, methods, computed, etc.)를 이용하여 구성 |
| 재사용성 | 로직을 기능별로 분리해 재사용하기 용이 | 여러 기능을 한 컴포넌트에 넣기 때문에 재사용성이 떨어질 수 있음 |
| 유지보수성 | 코드의 의도를 명확히 분리하여 유지보수성이 높음 | 하나의 객체에 모든 것을 정의하므로 복잡한 컴포넌트는 관리하기 어려움 |
| 타입스크립트 지원 | 타입스크립트와 잘 통합되며, 명시적 타입 정의가 가능 | 타입스크립트 사용 시 옵션마다 타입을 명시해야 해서 다소 복잡 |
| 학습 곡선 | 처음에는 다소 복잡할 수 있지만, 익숙해지면 유연하고 강력함 | Vue에 익숙한 사람이라면 배우기 쉽고 직관적 |
왜 Composition API를 사용할까?
- 코드 재사용: Composition API는 기능별로 코드를 나누어 더 쉽게 재사용할 수 있게 만든다.
- 유지보수성: 비슷한 기능을 가진 코드들을 한 곳에 모아서 관리할 수 있어 유지보수가 용이하다.
- 타입스크립트 친화적: Composition API는 타입스크립트와 함께 사용하기 더 자연스럽고, 코드에 대한 타입 추론을 잘 지원한다.
- 클린 코드: 비슷한 기능들을 한 파일에 묶어서 컴포넌트가 커지는 문제를 해결할 수 있다.
-> 유연한 방식의 컴포넌트 작성으로 특히 대규모 애플리케이션에서 코드의 재사용성과 유지보수성을 크게 향상시킬 수 있다.
Composition API의 주요 기능과 함수들
1. setup(): Composition API에서 가장 중요한 함수. setup()은 컴포넌트가 생성될 때 호출되며, 데이터, 메소드, 계산된 속성, 라이프사이클 훅 등을 선언. 이곳에서 선언된 값들은 컴포넌트 내에서 사용할 수 있다.
2. ref(): ref()는 반응형 데이터를 만들 때 사용. 이 함수로 만든 데이터는 vue의 반응성 시스템에 의해 자동으로 추적되고 업데이트 된다.
* setup()과 ref()를 사용한 코드예시
<template>
<div>{{ count }}</div>
<button @click="increment">Increment</button>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const count = ref(0); // 반응형 상태
const increment = () => {
count.value++;
};
return { count, increment }; // 템플릿에서 사용할 값 반환
}
}
</script>
3. reactive(): reactive()는 객체를 반응형으로 만들어주는 함수로 객체나 배열을 반응형 상태로 만들 때 사용.
const state = reactive({
count: 0,
name: 'Vue'
});
4. computed(): computed()는 계산된 속성을 만들 때 사용하는데 특정 값이 변경될 때만 계산되므로 성능상 유리하다.
const doubledCount = computed(() => count.value * 2);
5. watch(): watch()는 특정 반응형 데이터의 변경을 감지하고 그에 따른 작업을 실행할 수 있게 해준다. 주로 상태 변화에 따라 비동기 작업을 처리할 때 유용하다. (폼요소)
watch(count, (newCount) => {
console.log('count가 변경됨:', newCount);
});
** watch 함수의 인자
- 첫 번째 인자: 감시할 반응형 데이터 또는 함수
- 두 번째 인자: 반응형 데이터가 변경될 때 실행될 콜백 함수
- (선택적) 세 번째 인자: 옵션 객체 (옵션으로 사용할 수 있는 추가 설정)
- 첫 번째 인자 : 감시할 데이터 = 반응형 데이터 또는 함수
- 반응형 데이터: ref나 reactive로 만든 데이터를 감시
- 함수: 상태나 계산된 속성(computed)을 감시하려면 그 값을 반환하는 함수를 사용할 수 있다. 이때 함수는 데이터의 변화를 감지할 수 있는 기준이 된다.
- 두 번째 인자: 콜백 함수
=> 두 번째 인자는 감시 대상이 변경될 때 호출될 콜백 함수. 이 함수는 다음 두 가지 인자를 받는다.
- newValue: 감시하는 데이터가 변경된 후의 새로운 값
- oldValue (선택적): 감시하는 데이터가 변경되기 전의 이전 값. oldValue는 두 번째 인자에서 선택적으로 사용할 수 있다.
const count = ref(0);
watch(count, (newCount, oldCount) => {
console.log('count가 변경됨. 이전 값:', oldCount, '새로운 값:', newCount);
});
위 예시에서 watch는 count라는 반응형 데이터를 감시하고, count의 값이 변경되면 두 번째 인자로 전달된 콜백 함수가 호출된다.
newCount는 count가 변경된 후의 값, oldCount는 변경되기 전의 값을 나타낸다.
- 세 번째 인자: 옵션 객체
=> 세 번째 인자는 옵션 객체로, watch의 동작 방식을 제어할 수 있는 추가 설정을 제공한다. 주요 옵션은 다음과 같다.
- immediate: true로 설정하면, 감시 시작 시점에서 즉시 콜백을 실행. 기본값은 false로, 데이터가 처음 변할 때만 콜백이 실행.
- deep: true로 설정하면, 객체나 배열의 내부 속성까지 깊이 추적하여 변경 사항을 감지. 기본값은 false.
const state = reactive({ count: 0, name: 'Vue' });
watch(
() => state, // 감시할 반응형 데이터
(newState, oldState) => {
console.log('상태가 변경되었습니다:', newState);
},
{ deep: true } // 객체 내부의 변화까지 추적
);
이 예시에서 deep: true를 설정하면, state 객체의 내부 속성인 count나 name이 변경될 때마다 watch 콜백이 실행.
6. onMounted(), onUpdated(), onUnmounted(): Composition API에서는 라이프사이클 훅을 함수 형태로 사용할 수 있다. onMounted()는 컴포넌트가 마운트된 후 실행되며, onUpdated()는 상태가 업데이트될 때 호출된다. onUnmounted()는 컴포넌트가 파괴될 때 실행된다.
import { onMounted } from 'vue';
onMounted(() => {
console.log('컴포넌트가 마운트되었습니다!');
});
** Pinia의 주요 특징
- composition API와 통합: pinia는 vue 3의 composition API와 매우 잘 통합된다. ref, reactive, computed 등의 vue 3 API를 사용할 수 있다.
- 모듈화: pinia는 스토어를 모듈화하여 여러 개의 스토어를 간편하게 관리할 수 있다. 각 스토어는 독립적으로 설정되고 사용가능하다.
- typescript 지원: typeScript를 기본적으로 지원하여, 타입 안전성을 제공한다.
- 단순한 API: pinia의 api는 vuex보다 간결하고 직관적이다. 설정이 적고, store를 정의하는 방식이 간단하다.
- devtools 통합: vue devtools와의 통합이 잘 되어 있어, 상태를 쉽게 추적하고 디버깅할 수 있다.
=> pinia는 vue 3에 최적화된 라이브러리로, vuex에 비해 더 직관적이고 간단한 설정을 제공한다.
vuex는 여전히 vue 2와의 호환성을 고려해 설계된 부분이 있기 때문에, vue 3에서는 pinia가 더 나은 선택이 될 수 있다.
** Pinia와 Vuex의 차이점
| 특징 | Pinia | Vuex |
| 설정 및 사용 | 훨씬 간단하고 직관적이며 설정이 적음 | 설정이 많고, 복잡한 구성 요소가 많음 |
| 상태 관리 | defineStore를 사용하여 상태를 정의, Composition API와 잘 통합됨 | state, getters, mutations, actions로 상태 관리 |
| 모듈화 | 각 스토어는 독립적이고 모듈화된 방식으로 관리 | 모듈 시스템이 있으나 상대적으로 복잡함 |
| typescript 지원 | 기본적으로 typescript를 잘 지원하며 타입 추론이 매우 좋음 | typescript를 지원하지만 설정이 더 번거로움 |
| vue devtools | pinia 전용 devtools 지원, 상태 추적이 직관적임 | vuex devtools 지원, 상태 추적이 가능하지만 다소 복잡함 |
| 반응성 | ref, reactive등 vue3의 composition API와 잘통함 | vuex의 상태는 반응성 구현이 상대적으로 복잡함 |
| 플러그인 시스템 | pinia자체가 가벼워서 플러그인 시스템을 쉽게 사용할 수 있음 | vuex 플러그인 시스템은 약간 복잡할 수 있음 |
** vuex 활용버전
vuex 설치 후, Store() 설정하기


vuex 에서 mapState, mapActions, mapMutations 등을 가져와 함수형식으로 사용하기

- vuex와 pinia의 차이로 주목해야할 점
** vuex에서의 mutations
vuex는 상태 관리 라이브러리로, 상태를 변경하는 방법에 대한 규칙을 엄격하게 제어.
**mutations**는 상태를 변경하는 유일한 방법으로 state를 수정하는 함수가 mutations 안에 정의된다. 이 방법은 동기적으로만 상태를 변경할 수 있게 하여 예측 가능한 방식으로 상태를 관리할 수 있도록 했다.


** pinia 활용버전 -> npm i pinia 설치 후 활용


useCounterStor()을 호출하여 등록된 함수를 적용

** Pinia에서의 상태 변경
pinia에서는 mutations 개념이 없다. 대신 상태(state)를 변경하는 로직을 바로 actions 안에서 처리.
actions는 상태를 변경하거나 비동기 작업을 처리할 수 있는 함수로 사용. 상태를 변경하는 데 특별한 제약이 없으며, actions 안에서 바로 state를 수정할 수 있다.
pinia에서 mutations를 없앤 이유
- 간소화된 코드: pinia에서는 상태 변경이 직접적이므로 별도로 mutation을 정의할 필요가 없어 코드가 더 간단하고 이해하기 쉬워짐
- vuex보다 더 유연한 상태 변경: mutation을 통해서만 상태를 변경해야 한다는 규칙이 없음. 코드가 더 유연해짐.
- Composition API와의 통합: pinia는 vue 3의 Composition API와 잘 통합되어, 상태를 쉽게 선언하고 조작할 수 있음. this를 통해 직접 상태를 수정하는 것이 Composition API의 방식과 더 잘 맞음
**mutations**가 아니라, **actions**에서 상태를 직접 수정하고 있다는 점. 이로 인해 상태 변경이 더욱 직관적이고 간편해진다.
*상태변경을 직접하는 pinia에서 actions의 예시

vuex에서는 상태를 변경할 때 mutations를 사용하여 상태 변경을 강제하고 그 변경은 반드시 mutations 내에서만 이루어진다.
그러나 Pinia에서는 mutations가 없고, 대신 **actions**에서 상태를 직접적으로 변경. actions는 동기적, 비동기적 상태 변경 모두를 처리할 수 있다. Pinia는 간단하고 직관적인 상태 관리를 제공하기 위해 mutations의 개념을 제거하고, 상태를 바로 수정할 수 있는 방법을 제공한다는 점. 이렇게 pinia는 vuex보다 더 직관적이고 가벼운 상태 관리 방식을 제공하며, Composition API와 잘 맞아 떨어진다.
'Vue' 카테고리의 다른 글
| [Vue] 네이버 지도맵 어플 유무에 따른 fallback 처리 (0) | 2025.09.04 |
|---|---|
| [Vue] v-bind:class 객체로 사용하기 (0) | 2025.03.08 |
| [Vue] vue3 + vite 깃허브 페이지 배포하기 (0) | 2025.02.16 |
| [Vue] Tailwind.css(with Nuxt.js) 시작하기 (0) | 2025.02.13 |
| [Vue] Nuxt.js 시작하기 (0) | 2025.02.11 |