Dewdew logo-mobile
Uses
Tech
Guestbook

Pinia: How to Use Vue3 State Management Pinia Effectively

Summary of the presentation from Vue Nation 2024: Discussing how not to use Pinia like Vuex.

vue3 vue nation 2024 pinia
dewdew

Dewdew

Jan 26, 2024

4 min read

cover

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!


Reference

Dewdew of the Internet © 2024