yarn add pinia @pinia/nuxt
# or with npm
npm install pinia @pinia/nuxt
1) TypeScript와 완전 호환
2) 전역 상태, 개별 Component의 로컬 상태 모두 관리 가능
3) reactive 함수를 사용하여 상태 관리, 상태 변화를 실시간으로 추적, 반응형 처리, 성능 최적화
import { defineStore } from 'pinia'
export const useAlertsStore = defineStore('alerts', {
// 옵션
})
<script setup>
import { useCounterStore } from '@/stores/counter'
// access the `store` variable anywhere in the component ✨
const store = useCounterStore()
</script>
interface IUser {
email: string
name: string
}
// auth 스토어
export const useAuthStore = defineStore('auth', {
state: () => {
return {
user: {
email: '',
name: ''
} as IUser
}
},
getters: {
getEmail: (state): string => state.user.email
},
actions: {
setUser(data: IUser) {
this.user = data
}
}
})
if (import.meta.hot) { //HMR(개발중 애플리케이션 수정 시 페이지 새로 고치지 않고 변경사항을 빠르게 반영)
import.meta.hot.accept(acceptHMRUpdate(useAuthStore, import.meta.hot))
}
<template>
<div>
<v-btn @click="handleLogin">로그인</v-btn>
<div>{{ getEmail }}</div>
</div>
</template>
<script setup lang="ts">
import { storeToRefs } from 'pinia'
import { useAuthStore } from '~/stores/auth'
// 스토어 생성
const authStore = useAuthStore()
// 반응형 객체로 변환
const { getEmail } = storeToRefs(authStore)
const handleLogin = () => {
const user = {
email: 'test@naver.com',
name: 'kim'
}
authStore.setUser(user)
}
</script>
<style scoped></style>
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const name = ref('Eduardo')
const doubleCount = computed(() => count.value * 2)
function increment() {
count.value++
}
return { count, name, doubleCount, increment }
})
ex)
<script setup>
import { useCounterStore } from '@/stores/counter'
import { storeToRefs } from 'pinia'
const store = useCounterStore()
const { name, doubleCount } = storeToRefs(store)
const { increment } = store
</script>
export default defineNuxtConfig({
//다른옵션
modules: ['@pinia/nuxt'],
pinia: {
storesDirs: ['./stores/**', './custom-folder/stores/**'],
},
})
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => {
return { count: 0 }
},
actions: {
increment() {
this.count++
},
},
})
<script setup>
import { useCounterStore } from '@/stores/counter'
const store = useCounterStore()
</script>
ex)
import { defineStore } from 'pinia'
export const useStore = defineStore('storeId', {
// arrow function recommended for full type inference
state: () => {
return {
// all these properties will have their type inferred automatically
count: 0,
name: 'Eduardo',
isAdmin: true,
items: [],
hasChanged: true,
}
},
})
export const useUserStore = defineStore('user', {
state: () => {
return {
// for initially empty lists
userList: [] as UserInfo[],
// for data that is not yet loaded
user: null as UserInfo | null,
}
},
})
interface UserInfo {
name: string
age: number
}
const store = useStore()
store.count++
const store = useStore()
store.$reset()
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
function $reset() {
count.value = 0
}
return { count, $reset }
})
export function myPiniaPlugin(context) {
context.pinia // `createPinia()`로 생성된 피니아
context.app // `createApp()`으로 생성된 현재 앱(Vue 3만 해당)
context.store // 플러그인이 확장되는 스토어
context.options // `defineStore()`에 전달된 스토어를 정의하는 옵션 객체
// ...
}
pinia.use(myPiniaPlugin)
import { createPinia } from 'pinia'
// 이 플러그인이 설치된 후 생성된 모든 저장소에 `secret`이라는 속성을 추가합니다.
// 이것은 다른 파일에 있을 수 있습니다.
function SecretPiniaPlugin() {
return { secret: '임금님 귀는 당나귀 귀!' }
}
const pinia = createPinia()
// 플러그인을 피니아에 제공
pinia.use(SecretPiniaPlugin)
// 다른 파일에서
const store = useStore()
store.secret // '임금님 귀는 당나귀 귀!'
// plugins/myPiniaPlugin.ts
import { PiniaPluginContext } from 'pinia'
function MyPiniaPlugin({ store }: PiniaPluginContext) {
store.$subscribe((mutation) => {
// react to store changes
console.log(`[🍍 ${mutation.storeId}]: ${mutation.type}.`)
})
// Note this has to be typed if you are using TS
return { creationTime: new Date() }
}
export default defineNuxtPlugin(({ $pinia }) => {
$pinia.use(MyPiniaPlugin)
})