Pinia Basics

Preview — 3 of 10 questions

What is Pinia and what does it replace in the Vue ecosystem?

javascript
// Vuex (old) — complex boilerplate
const store = new Vuex.Store({
  state: { count: 0 },
  mutations: {
    increment(state) { state.count++ }  // Must use mutations for sync changes
  },
  actions: {
    incrementAsync({ commit }) {
      setTimeout(() => commit('increment'), 1000)
    }
  },
  getters: {
    double: state => state.count * 2
  }
})

// Pinia (new) — simple and intuitive
const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  getters: {
    double: (state) => state.count * 2
  },
  actions: {
    increment() { this.count++ }, // Direct mutation — no separate mutations needed!
    async incrementAsync() {
      await sleep(1000)
      this.count++
    }
  }
})
APinia is a UI component library that replaces Vuetify
BPinia is the official Vue state management library that replaces Vuex, offering a simpler API and first-class TypeScript support
CPinia is a Vue plugin for server-side rendering that replaces Nuxt
DPinia is a testing utility that replaces Vue Test Utils

How do you install and set up Pinia in a Vue 3 application?

javascript
// main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const app = createApp(App)
const pinia = createPinia()

// IMPORTANT: Register Pinia BEFORE the router if guards use stores
app.use(pinia)
app.use(router) // After Pinia
app.mount('#app')
Aimport { createPinia } from 'pinia'; app.use(createPinia())
Bimport Pinia from 'pinia'; Vue.use(Pinia)
Cimport { usePinia } from 'pinia'; usePinia(app)
Dimport pinia from 'pinia'; app.mount('#app', { pinia })

What is the correct way to define a Pinia store?

javascript
import { defineStore } from 'pinia'

// Options syntax (similar to Options API)
export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0,
    name: 'Counter'
  }),
  getters: {
    double: (state) => state.count * 2,
    // Access other getters via this
    quadruple(): number { return this.double * 2 }
  },
  actions: {
    increment() {
      this.count++ // Direct mutation via this
    },
    async fetchCount() {
      const data = await api.getCount()
      this.count = data.count
    }
  }
})

// Usage in component
import { useCounterStore } from '@/stores/counter'

const counter = useCounterStore()
counter.increment()
console.log(counter.count)  // 1
console.log(counter.double) // 2
Aconst store = new PiniaStore('counter', { state: { count: 0 } })
Bconst useCounterStore = reactive({ id: 'counter', count: 0 })
Cconst store = createStore({ id: 'counter', state: { count: 0 } })
Dconst useCounterStore = defineStore('counter', { state: () => ({ count: 0 }) })

Sign up free to play

Answer all 10 questions (7 more), see explanations for every answer, and track your score.