Pinia: State Management Global

Berbagi state antar banyak komponen dengan Pinia: defineStore (setup store), state, getters, actions, storeToRefs, dan kapan memakainya.

Part 22 dari 25 ± 50 menit Gratis

Kapan state perlu dibuat global?

Props dan emits cukup untuk komunikasi induk-anak. Tetapi data seperti isi keranjang belanja, pengguna yang login, atau preferensi tema dibutuhkan banyak komponen di halaman berbeda. Meneruskannya lewat props berlapis-lapis sangat merepotkan. Solusinya: sebuah store terpusat yang bisa diakses komponen mana pun.

Pinia adalah pustaka state management resmi Vue — ringan, sederhana, dan mendukung devtools.

npm install pinia

// main.js
import { createPinia } from 'pinia'
createApp(App).use(createPinia()).mount('#app')

Membuat store (setup store)

Gaya setup store sama persis dengan menulis <script setup>: ref = state, computed = getters, fungsi = actions.

// stores/keranjang.js
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

export const useKeranjang = defineStore('keranjang', () => {
  const items = ref([])                                          // state
  const jumlah = computed(() => items.value.length)              // getter
  const total = computed(() => items.value.reduce((t, i) => t + i.harga, 0))

  function tambah(item) { items.value.push(item) }               // action
  function kosongkan() { items.value = [] }

  return { items, jumlah, total, tambah, kosongkan }             // wajib di-return
})

Argumen pertama 'keranjang' adalah ID unik store. Apa pun yang tidak di-return bersifat privat.

Memakai store di komponen

<script setup>
import { useKeranjang } from '@/stores/keranjang'
const keranjang = useKeranjang()
</script>

<template>
  <p>{{ keranjang.jumlah }} barang — Rp {{ keranjang.total }}</p>
  <button @click="keranjang.tambah({ nama: 'Buku', harga: 50000 })">Beli</button>
</template>

Semua komponen yang memanggil useKeranjang() memperoleh store yang sama. Perubahan di satu tempat langsung terlihat di tempat lain.

Destructuring: pakai storeToRefs

import { storeToRefs } from 'pinia'

const keranjang = useKeranjang()
const { items, jumlah, total } = storeToRefs(keranjang)   // state & getter tetap reaktif
const { tambah, kosongkan } = keranjang                    // action boleh langsung dipecah

Memecah state langsung (const { jumlah } = keranjang) memutus reaktivitas. Gunakan storeToRefs untuk state/getter.

Option store (gaya alternatif)

export const useHitung = defineStore('hitung', {
  state: () => ({ n: 0 }),
  getters: { ganda: (s) => s.n * 2 },
  actions: { tambah() { this.n++ } },
})
KonsepSetup storeOption store
Stateref()state: () => ({})
Gettercomputed()getters
Actionfungsiactions

Action asinkron

async function muat() {
  loading.value = true
  try { items.value = await (await fetch('/api/produk')).json() }
  finally { loading.value = false }
}

Kapan TIDAK perlu Pinia?

  • State hanya dipakai satu komponen atau induk-anak langsung → ref + props/emits.
  • Logika yang dipakai ulang tapi state-nya harus terpisah per pemakai → composable.
  • Tema/bahasa untuk satu cabang komponen → provide/inject.

Kesalahan umum

  • Lupa app.use(createPinia()) → error "getActivePinia() was called but there was no active Pinia".
  • Tidak me-return state/action dari setup store.
  • Memasukkan semua state ke Pinia padahal cukup lokal.

Praktikkan langsung, gratis

Tulis dan jalankan kode langsung di browser, dapatkan penilaian otomatis. Daftar gratis kapan saja untuk menyimpan progres dan meraih sertifikat.

Coba latihan sekarang, tanpa daftar
Bagikan: WhatsApp Facebook LinkedIn X