> For the complete documentation index, see [llms.txt](https://pinia.chocopam.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://pinia.chocopam.com/introduction/why-pinia/vuex-vs-pinia.md).

# Vuex VS Pinia

## Vuex와의 차이점&#x20;

### Vuex란?

Vue3 composition API 이전 Vue2 options API를 사용할때 사용했던  전역 상태 관리 도구입니다.

Vuex는 Vue3 부터는 버전 업그레이드를 중단했으며 Vue3의 공식적인 전역 상태관리 도구인 Pinia를 사용하라고 권장하고 있습니다.

### 모듈 vs 다중 스토어(store)&#x20;

Vuex에서는 앱 전체에서 사용하는 중앙 스토어를 하나 만들어 두고 한 스토어 안에 여러 개의 모듈을 연결하여 사용합니다.

각 컴포넌트에서는 앱 전체에서 유일하게 존재하는 스토어를 참조하여 각 모듈안의 상태 값을 가져다 사용했습니다.

#### 프로젝트 내부에서 Vuex의 폴더 구조&#x20;

```
src/
|-- store/
    |-- index.js             # Main store file where you combine modules
    |-- state.js             # Root state (optional, can be in index.js)
    |-- mutations.js         # Root mutations (optional, can be in index.js)
    |-- actions.js           # Root actions (optional, can be in index.js)
    |-- getters.js           # Root getters (optional, can be in index.js)
    |-- modules/
        |-- user.js          # User module (state, mutations, actions, getters)
        |-- cart.js          # Cart module (state, mutations, actions, getters)
        |-- products.js      # Products module (state, mutations, actions, getters)
        # ... other modules
```

#### 프로젝트 내부에서 Pinia의 폴더 구조

```
src/
|-- stores/
    |-- userStore.js        # User store with its own state, actions, getters
    |-- cartStore.js        # Cart store with its own state, actions, getters
    |-- productsStore.js    # Products store with its own state, actions, getters
    # ... other stores
```

Pinia는 여러 모듈을 만들어 하나의 스토어에 할당하는 개념이 아닌, 여러 개의 스토어를 생성하는 개념입니다.

### Vue2에서의 Vuex 사용방식&#x20;

#### 모듈 위치 파악이 어렵다.

options api에서 각 모듈의 상태값과 액션들을 가져와서 사용해야 합니다.&#x20;

이때 불편한 점으로 각 모듈간 getter, state, action 이름이 동일할 경우 충돌이 일어날 수 있는데 namespace로 충돌을 방지할 수 있습니다.

하지만 namespace를 사용하더라도 최상위 스토어에서 namespace와 모듈 이름이 다르게 선언되고 모듈이 여러개가 정의되는 경우 모듈 코드를 찾기 까다롭고 복잡해집니다.

#### namespace 사용 예시&#x20;

```html
<script>
import { mapGetters, mapActions } from 'vuex';

export default {
  name: 'UserProfileComponent',
  computed: {
    ...mapGetters('userProfile', ['userName'])
  },
  methods: {
    ...mapActions('shoppingCart', ['updateUserName'])
  }
};
</script>

```

options API를 사용하는 UserProfileComponent의 구현 내부입니다. `userProfile`, `shoppingCart` 두개의 스토어를 사용합니다.

```javascript
// store/user.js
export const userModule = {
  namespaced: true,
  state: { ... },
  // other options like mutations, actions, getters
};

// store/cart.js
export const cartModule = {
  namespaced: true,
  state: { ... },
  // other options
};

// store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
import { userModule } from './user';
import { cartModule } from './cart';

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    userProfile: userModule,
    shoppingCart: cartModule
  }
});

```

Vuex 스토어가 선언될 때 각 모듈의 namespace 이름은 userProfile, shoppingCart로 선언되었는데 파일이름은 \~Module로 표기되고 있습니다. `store/index.js` 파일에 들어가 실제 모듈 파일 이름을 확인하기 전까지는 모듈 정의부를 보기가 어려워집니다.

#### Vue3에서 Pinia 사용

리엑트 훅처럼 스토어를 직접 각 컴포넌트 레벨로 가져와 사용하기 때문에 정의부를 탐색하기 쉽습니다.

```
<template>
  <div>
    <p>User name: {{ userName }}</p>
    <button @click="updateName('Jane Doe')">Change Name</button>
  </div>
</template>

<script>
import { useUserStore } from '@/stores/userStore';

export default {
  setup() {
    const userStore = useUserStore();
    const updateName = (newName) => userStore.updateName(newName);

    return { userName: userStore.name, updateName };
  },
};
</script>

```
