Pinia Lanjutan — Vue

Composition API Store export const useTodoStore = defineStore("todos", () => { const todos = ref([]) const filter = ref("all") const filteredTodos =…

Di pelajaran sebelumnya store keranjang cuma menghitung jumlah dan total. Keranjang sungguhan menyimpan daftar menu: tiap menu bisa ditambah dan dibuang, totalnya dihitung dari daftar itu, dan di akhir hari semuanya dikosongkan. Pelajaran ini melengkapi store-nya: state berupa array, getter dengan computed, action yang menambah dan membuang, storeToRefs, $patch, dan $reset. Bayangin lagi papan di dinding dapur Warung Bu Sri. Sekarang tiap pesanan ditulis satu baris, angka total di bawahnya selalu dijumlah ulang dari baris-baris itu, satu baris bisa dicoret, dan saat warung tutup papannya dihapus bersih seperti pagi hari.

🧪 Tebakan cepat: Store keranjang ditulis gaya setup. Saat warung tutup, kode memanggil keranjang.$reset(). Di build production, apa yang terjadi pada isi keranjang? Tebak dulu, jawabannya ada di bagian "$patch dan $reset".

Store gaya setup yang lengkap

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

export const useKeranjangStore = defineStore("keranjang", () => {
  const items = ref([])
  const meja = ref(null)
  let nomor = 0

  const total = computed(() => items.value.reduce((jumlah, item) => jumlah + item.harga, 0))

  function tambah(menu) {
    items.value.push({ id: ++nomor, nama: menu.nama, harga: menu.harga })
  }
  function hapus(index) {
    items.value.splice(index, 1)
  }
  function kosongkan() {
    items.value = []
    meja.value = null
  }

  return { items, meja, total, tambah, hapus, kosongkan }
})
Kejadian items total
awal [] 0
tambah(Nasi Goreng) Nasi Goreng 15000 15000
tambah(Es Teh) Nasi Goreng 15000, Es Teh 5000 20000
hapus(0) Es Teh 5000 5000
kosongkan() [] 0

Komponen keranjang memakainya begini:

<script setup>
import { storeToRefs } from "pinia"
import { useKeranjangStore } from "../stores/keranjang"

const keranjang = useKeranjangStore()
const { items, total } = storeToRefs(keranjang)
const { hapus } = keranjang
</script>

<template>
  <ul>
    <li v-for="(item, i) in items" :key="item.id">
      {{ item.nama }} Rp{{ item.harga }}
      <button @click="hapus(i)">×</button>
    </li>
  </ul>
  <p>Total: Rp{{ total }}</p>
</template>

storeToRefs: state dan getter jadi ref, action diambil langsung

Ditulis Isinya
storeToRefs(keranjang) items, meja, total: state dan getter, semuanya ref
const { hapus } = keranjang action-nya, langsung dari store

$patch dan $reset

Setiap store punya beberapa method bawaan yang diawali $.

keranjang.$patch({ meja: 4 })              // ubah beberapa state sekaligus

keranjang.$patch((state) => {              // bentuk fungsi, enak untuk array
  state.items.push({ id: 99, nama: "Es Teh", harga: 5000 })
  state.meja = 7
})

$reset() mengembalikan state ke nilai awalnya, tapi cuma di store gaya options, karena di sana Pinia bisa memanggil state() lagi:

export const useKeranjangStore = defineStore("keranjang", {
  state: () => ({ items: [], meja: null }),
  getters: {
    total: (state) => state.items.reduce((jumlah, item) => jumlah + item.harga, 0),
  },
})

keranjang.$reset()   // items: [], meja: null, jadi total 0

Store gaya setup gak punya state() untuk dipanggil ulang. Di build production, $reset() gak melakukan apa-apa: isi keranjang tetap. Itu jawaban tebakannya. Build development malah berhenti dengan pesan ini:

🍍: Store "keranjang" is built using the setup syntax and does not implement $reset().

Untuk store gaya setup, tulis action pengosong sendiri, seperti kosongkan() di atas.

🎯 Store memakai store lain

Sebuah store boleh memanggil store lain, misalnya keranjang yang menolak pesanan saat warung tutup:

export const useKeranjangStore = defineStore("keranjang", () => {
  const warung = useWarungStore()
  const items = ref([])

  function tambah(menu) {
    if (!warung.buka) return
    items.value.push({ ...menu })
  }

  return { items, tambah }
})

⚠️ Jebakan yang sering ketemu

TL;DR: Di store gaya setup, ref adalah state, computed adalah getter (misalnya total dari items.value.reduce(...)), dan fungsi adalah action (push untuk menambah, splice(index, 1) untuk membuang). storeToRefs() mengambil state dan getter sebagai ref tanpa kehilangan reaktivitas; action diambil langsung dari store. $patch mengubah beberapa state sekaligus, lewat objek atau fungsi. $reset() mengembalikan state ke nilai awal, tapi cuma di store gaya options; store gaya setup butuh action pengosong sendiri. Store boleh memakai store lain di dalam setup-nya.

Yang akan kamu pelajari