https://pinia.vuejs.org/cookbook/migration-vuex.html
Vue 2버전대 레포를 Vue3 로 버전업을 하였는데요.
상태관리라이브러리 역시도 Vue3 와 호환성이 좋은 Pinia 로 마이그레이션을 할려고 합니다. (vue공식 홈에서도 Pinia 사용을 권장하기도 함)
Vuex는 Vue.js 애플리케이션에서 상태 관리를 위한 공식 라이브러리로, Vue 2와 함께 널리 사용되었습니다. 그러나 Vue 3가 출시되면서 새로운 상태 관리 라이브러리인 Pinia가 등장했습니다. Pinia는 Vuex의 단점을 보완하고, Vue 3의 Composition API와 더 잘 어울리도록 설계되었습니다.
아래는 Vuex 4 → Pinia 로 마이그레이션한 과정을 적어봤습니다.
CodeBase
🁢 node version 20.15.0
🁢 vue version ^3.1.0
🁢 vuex version 4
pinia 공식 홈페이지에서 Vuex -> Pinia 로 마이그레이션 하는 방법을 아래와 같이 제안합니다.
이전(vuex 스토어) 네임스페이스를 보존하며 [🔗src/store /..],
pinia 디렉토리를 생성해줍니다. [🔗src/stores /...]
마이그레이션 중에 Pinia와 Vuex를 함께 혼합할 수 있으므로 이 접근 방식도 작동할 수 있습니다.
공식홈 추천 사항
- camelCase 로 id하는 것이 좋다.
- mutations는 더이상 필요하지 않다. → actions 로 하거나, 구성 요소 내의 스토어에 직접 할당 할 수 있다.
[Vue Router 내비게이션 가드에서 스토어를 사용하는 예]
설치 및 적용
설치
yarn add pinia
main.js
- pinia 플러그인 설치
import { createPinia } from 'pinia';
app.use(createPinia());
stores/index.js → optional , 필요시 생성
export { useAuthStore } from "./authStore";
export { useUserStore } from "./userStore";
...
authStore [Vuex → Pinia migration]
해당 스토어는 로그인, 로그아웃, 회원가입 등을 상태관리하는 곳입니다.
폴더구조
- state: Vuex의 state를 state() 함수로 정의.
- actions: Vuex의 actions를 Pinia의 actions로 직접 매핑.
- getters: Vuex의 getters를 Pinia의 getters로 변경하여 계산된 상태 제공.
- 간결화: Context 객체 제거 (state, commit, dispatch 불필요)
Authentication 이 작동하는 방식을 정리해보면,
1️⃣ Client 가 Server 에 로그인을 요청을 합니다.
2️⃣ id 와 password 가 일치한다면 Server 는 JWT토큰을 생성하여 Client 에 반환해줍니다.
3️⃣ Client 는 Server 로부터 받은 JWT토큰을 LocalStorage 에 저장을 합니다.
4️⃣ Client 에서 API 호출 시 HTTP request header 에 LocalStorage 에 저장된 JWT토큰을 실어서 전송을 합니다.
5️⃣ Client 가 로그아웃을 하면 로그아웃 API 호출 및 LocalStorage 에서 JWT토큰을 제거합니다.
Vue.js 에서 (+Vuex) Authentication 구현 과정은
1️⃣ Register users
- 사용자 등록 시 데이터 유효성 검증(클라이언트 및 서버) 수행.
- 서버로부터 토큰 및 사용자 정보 반환.
2️⃣ Login users
- 사용자 인증 후 `userData`({token, email, name 등}) 반환.
userData = {
token: "JWT_TOKEN",
email: "user@example.com",
name: "eona"
}
- HTTPS 및 보안 헤더 사용 권장(: 반환된 token은 반드시 HTTPS를 통해 전달되어야 함).
3️⃣ Vuex
- `userData`를 Vuex State와 `localStorage`에 저장. (sessionStorage도 사용가능)
- `axios`의 default 헤더에 토큰 추가(Bearer 형식).
- 필요한 경우, `axios` interceptor로 토큰 관리.
4️⃣ Access protected data
- 인증된 요청만 가능한 API 호출.
- 401 응답 처리 및 재인증 플로우 구현 고려 (토큰이 만료되었거나 유효하지 않음을 알리는 처리 로직(예: 로그아웃 또는 토큰 재발급 요청)).
5️⃣ Logout
- Vuex State 및 localStorage에서 `userData` 제거.
- `axios` default 헤더에서 토큰 제거.
- 로그아웃 후 리다이렉트 처리.
- Refresh Token 무효화 고려.
로컬 스토리지를 관리하기 위해 인기 있는 라이브러리 “@vueuse/core”를 사용할 수 있습니다.
yarn add @vueuse/core
“useLocalStorage” 함수는 “@vueuse/core” 라이브러리에서 제공합니다.
import { defineStore } from "pinia";
import jwt from "jsonwebtoken";
import axios from "@/helpers/axios";
import { useLocalStorage } from "@vueuse/core"; 👈add!
export const useAuthStore = defineStore("auth", {
state: () => ({
accessToken: useLocalStorage("accessToken", null), // 인증 토큰을 localStorage에 저장
refreshToken: useLocalStorage("refreshToken", null), // 리프레시 토큰을 localStorage에 저장
}),
actions: {
...
}
});
라이브러리 사용으로 코드를 간단하게 작성할 수 있습니다.
- 상태 값이 자동으로 브라우저의 localStorage에 저장되고, 새로고침 후에도 유지됩니다.
- accessToken과 refreshToken을 로컬 스토리지에 저장하여 사용자가 인증 상태를 유지할 수 있도록 합니다.
추가적으로 authStore 파일의 actions 에는 아래 사항들을 관리해주면 됩니다
- login
- 사용자가 로그인할 때 API 요청을 통해 액세스 토큰과 리프레시 토큰을 받아 state와 localStorage에 저장.
- logout
- 사용자 로그아웃 시, accessToken과 refreshToken을 제거하고 상태를 초기화.
- refreshAccessToken
- refreshToken을 사용하여 만료된 accessToken을 갱신.
- isTokenExpired (JWT 관련)
- jwt 라이브러리를 사용하여 accessToken의 만료 여부를 확인.
참고
'Vue.js' 카테고리의 다른 글
Vue3 + vite 에 Typescript 적용하기 (0) | 2025.01.08 |
---|---|
[Vue.js] Vue3 환경에서 Storybook 설치 및 Pagination 공통 컴포넌트 적용기 (0) | 2024.12.18 |
[Vue.js] Vue2 탈출기: Vue3 마이그레이션 가이드 (1) | 2024.12.18 |
[Vue.js] Vue2 프로젝트, Webpack에서 Vite로 마이그레이션하기! (0) | 2024.07.31 |
[Vue.js] Vue 프로젝트, ESLint, Prettier (+typescript) 설정하기! (1) | 2024.06.16 |