What is Pinia?
Pinia is a state management library in Vue3 & Nuxt3, providing similar functionalities to Vuex.
Unlike Vuex, Pinia
uses the Composition API
for state management.
Also, without the concepts of mutation, action, getter, etc., you can use the Store
value reactively.
In the past, Vuex was widely used, but with Vue3, Pinia is now predominantly used.
During the Vue Nation 2024 session, Eduardo San Martin Morote
, the creator of Pinia, conducted a session on how to use Pinia effectively.
The following content shares insights gained from the session.
1.No More Need for Mutations
In Vuex
, you could manage global state through state, mutations, actions, getters
as shown below.
// vuex
const store = createStore({
state: () => ({
count: 0,
isHidden: true
}),
mutations: {
increment(state) {
state.count++
},
toggle(state) {
state.isHidden = !state.isHidden
}
}
})
// getting state value in component
store.state.count
store.state.isHidden
// mutation in component
store.commit('increment')
store.commit('toggle')
In Vuex, to change the state, you had to use mutations.
However, in Pinia, you can directly change the state
.
// pinia
const useToggleStore = defineStore('toggle', {
const count = ref(0)
const isHidden = ref(true)
return {
count,
isHidden
}
})
// mutaions in component
const { count, isHidden } = sotreToRefs(useToggleStore())
count.value++
isHidden.value = false
2.Various Advantages of Pinia
And Pinia has following advantages.
- Pinia supports
Type safety
. - Pinia supports
Modular stores
. - Pinia supports
Better code splitting
. - Pinia uses
composition API
.
3.Type Management
In Vuex, type management was done outside of the store as follows.
// wrong
cosnt state: State = {
//...
}
defineStore('...', {
state: () => state,
})
However, in Pinia, you should not do as above, instead, you need to directly specify types within the store
like below.
// correct
defineStore('...', {
state: (): State => ({
//...
})
})
4.Read-Only Store
To build read-only store
in Pinia, you need to modify the code example as follows.
// before
const useStore = defineStore('...', {
const user = ref()
return {
// no Plugins, devtools, SSR
userReadonly: readonly(user),
// not state
get userGetter () {
return user.value
},
// not state
userComputed: computed(() => user.value)
}
})
// after
const useStore = defineStore('...', {
const user = ref()
return {
_user: user,
// valid gatter
user: computed(() => user.value)
}
})
Or, you can manage it by creating Private Store as below.
This allows you to create variables that can only be used within specific store
.
const usePrivateStore = defineStore('...', {
const user = ref()
return {
user
}
})
const userStore = defineStore('...', {
const privateStore = usePrivateStore()
privateStore.user // only within the store
return {
// no user exposed
}
})
5.Typescript
As shown in the example, when writing TypeScript for a store, it is better to use generics
to specify types rather than using ~ as
as below.
// not good
const useUserStore = defineStore('user', {
const userToken = ref({} as UserToken)
const user = ref({} as User)
return {
userToken,
user
}
})
// good
const useUserStore = defineStore('user', {
const userToken = ref<UserToken | null>(null) // For initialize with null
const user = ref<User>() // For handling undefined
return {
userToken,
user
}
})
6.Using Store in Script
If you use it as shown in the example below, Pinia will throw an error. When using the Composition API, you only need to call store once
within setup
.
// wrong
<script setup>
import { useModalStore } from './store/modal'
function someMethod () {
const modalStore = useModalStore()
}
watch(something, () => {
const modalStore = useModalStore()
})
</script>
// good
<script setup>
import { useModalStore } from './store/modal'
const modalStore = useModalStore()
function someMethod () {
modalStore //
}
watch(something, () => {
modalStore //
})
</script>
That’s all!
I’ve discussed more than the information I’ve gathered, but I’ve only summarized up to this point today!
Ongoing Vue nation 2024
has many excellent sessions, and I believe it’s a great opportunity to gain good insights
.
I hope you take away some valuable information.
See you next!