Vue의 공식 상태 관리 라이브러리가 Pinia 로 변경되었습니다 . Pinia는 Vuex 5 RFC 에 설명된 Vuex 5와 거의 동일하거나 향상된 API를 가지고 있습니다. Pinia를 다른 이름의 Vuex 5로 생각할 수 있습니다.
defineStore
라는 함수를 이용하여 각각의 파일마다 별도의 store를 정의하여 module의 기능을 대신합니다.vuex에서는core concepts로 state
,Getters
, Mutations
, Actions
, Modules
총 5가지 개념을 도입했습니다.
Pinia에서는 state
,Getters
,action
로 세가지 개념을 사용합니다. (모듈화는 필수적으로 적용되게 됩니다.)
mutations이 없어 권한이 없어 사용하기 편한 대신에 그로인해 발생하는 에러에 대한 책임을 져야합니다.
$ npm i pinia
vuex를 사용할 때는 store폴더를 만들어 그 안에 index.js라는 기본 파일을 만들었습니다.
만약, message라는 이름으로 모듈화를 하는 경우 store폴더 안에는 모듈이 하나더라도 message.js와 index.js파일로 총 2개의 파일이 존재해야했습니다.
하지만, pinia는 index.js 없이 모듈화된 파일만 있으면 됩니다.
또한 vuex에서는 모듈화된 파일의 상단에 namedspaced:true
가 필요했습니다. 하지만 피니아는 모듈이 기본 옵션이기에 따로 필요하지 않습니다.
store>message.js
import {defineStore} from 'pinia'
//이름을 가지는 내보내기
//첫번쨰 인수로 사용하고자 하는 모듈의 이름을 넣어줘야합니다
export const useMessageStore = defineStore('message'⭐,{
//화살표함수로 하면 좋습니다.
state: () => ({
message: 'Hello world!'
}),
getters: {
reversedMessage(state) {
return state.message.split('').reverse().join('')
}
},
actions: {
reverseMessage() {
//this로 접근
this.message = this.message.split('').reverse().join('')
}
},
})
🔑이름을 가지는 내보내기를 할 때 보통 이름 앞에 use를 붙여 사용합니다.
vuex에서는 mutations에서 state에 접근하기 위해 state라는 매개변수를 사용했습니다. 마찬가지로 pinia에서도 getters에서 state에 접근하기 위해 state를 매개변수로 받습니다.
vuex에서는 actions의 매개변수로 context(={state,getters,commit,dsipatch})를 사용했습니다.
하지만 pinia에서는 this를 통해 보다 편하게 접근을 할 수 있습니다.
vuex에서는 아래와 같이 state의 정보를 가져올 수 있었습니다.
computed: {
message() {
return this.$store.state.message.message
}
}
만약 매핑을 하는 경우 아래와 같이 사용할 수 있었습니다.
import {mapState} from 'vuex'
computed: {
...mapState('message', [
message
]),
}
하지만 pinia에서는 첫번째 방법은 사용을 할 수 없습니다
about.vue
import {mapState} from 'pinia' //1
import {useMessageStore} from '~/store/message' //2
export default {
computed: {
...mapState(useMessageStore, [ //3
'message'
])
}
}
mapState을 사용하는 경우 마찬가지로 pinia에서 mapState를 가지고 와 등록하면 됩니다.
단 피니아는 모든 것이 모듈이기 때문에 그 모듈을 직접가져와야합니다.
그리고 vuex에서는 모듈이름이 들어갔던 자리에 모듈을 통채로 집어넣습니다
main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'✅
import router from './routes'
import '~/routes/guards'
import App from './App.vue'
createApp(App)
.use(createPinia())✅호출합니다
.use(router)
.mount('#app')
About.vue
<template>
<h1>About!</h1>
<RouterLink to="/about/name">
Name~
</RouterLink>
<RouterView />
<div>{{ message }}</div>
</template>
import {mapState, mapGetters} from 'vuex'
와 같이 mapGetters를 가져왔습니다
getter도 mapState에서 가지고 옵니다.
<template>
<h1>About!</h1>
<RouterLink to="/about/name">
Name~
</RouterLink>
<RouterView />
<div>{{ message }}</div>
<div>{{ reversedMessage }}</div>
</template>
<script>
import {mapState} from 'pinia'
import {useMessageStore} from '~/store/message'
export default {
computed: {
...mapState(useMessageStore, [
'message',
'reversedMessage'
])
}
}
</script>
mapActions에서 actions를 가져올 수 있습니다.
<template>
<h1>About!</h1>
<RouterLink to="/about/name">
Name~
</RouterLink>
<RouterView />
<div>{{ message }}</div>
<div>{{ reversedMessage }}</div>
<button @click="reverseMessage">
Reverse!!
</button>
</template>
<script>
import {mapState, mapActions✅} from 'pinia'
import {useMessageStore} from '~/store/message'
export default {
computed: {
...mapState(useMessageStore, [
'message',
'reversedMessage'
])
},
methods: {✅
...mapActions(useMessageStore,[
'reverseMessage'
])
}
}
</script>
mapState, mapActions대신 사용할 수 있는 개념이 새로 나왔습니다.
등록하는 방법
<script>
import {mapStores} from 'pinia'
import {useMessageStore} from '~/store/message'
export default {
computed: {
...mapStores([useMessageStore])
},
}
</script>
위와 같이 등록을 해줍니다.
사용하는 방법
<template>
<h1>About!</h1>
<RouterLink to="/about/name">
Name~
</RouterLink>
<RouterView />
<div>{{✅ messageStore.message }}</div>
<div>{{✅ messageStore.reversedMessage }}</div>
<button @click="✅messageStore.reverseMessage">
Reverse!!
</button>
</template>
useMessageStore
에서 use를 뺀 객체데이터를 붙여줍니다.
messageStore
라는 이름 범위 안에서 사용을 하기 때문에 관리가 조금 더 용이합니다.
<button @click="messageStore.message='HEROPY?!@'">
HEROPY
</button>
위와 같이 state의 데이터를 수정해버릴 수도 있습니다.
참고
안녕하세요
올려주신 글 잘 보았습니다
궁금한 점이 있어서 댓글을 남깁니다
main.js 자체에서 pinia를 사용하여 store를 수정 할 수 있을까요?
ex) vue로 만들어진 홈페이지나 app을 접속 하면 main에서 아이디값을 localstorage를 확인 후 있으면 로그인 처리한다
이런식으로 하고 싶습니다 가능 할까요?