Vue · Bab 7
Pinia: State Bersama
Membedakan state lokal komponen dari state bersama, membuat store Pinia gaya setup dengan state, getter, dan action, memakainya di beberapa komponen dan rute, serta tahu kapan store tidak dibutuhkan.
Sampai bab 6, setiap komponen menyimpan datanya sendiri dengan ref. Itu cukup selama data hanya dipakai satu komponen. Begitu dua komponen yang berjauhan membutuhkan data yang sama, misalnya daftar buku yang akan dipinjam, kamu butuh state bersama. Di Vue, tempatnya adalah store Pinia.
7.1 Masalahnya: Data yang Dipakai Banyak Komponen
Bayangkan aplikasi peminjaman Perpustakaan Pelita. Anggota memilih buku di halaman koleksi; jumlah buku pilihan tampil di header; daftarnya tampil lagi di halaman konfirmasi. Tiga komponen, satu data.
Dengan props dan emit (bab 3), data harus disimpan di komponen induk paling atas, lalu dioper turun lewat props ke setiap lapisan dan dikabarkan naik lewat emit dari setiap lapisan, termasuk lapisan yang sebenarnya tidak memakainya. Semakin dalam pohon komponennya, semakin repot. Store memecahkannya: data disimpan di satu tempat di luar komponen, dan komponen mana pun yang butuh langsung mengambilnya.
7.2 Store Pertama
Store dibuat dengan defineStore(id, setup). Bab ini memakai gaya setup, sama dengan setup() komponen yang sudah kamu kenal:
| Di dalam store | Peran |
|---|---|
ref(...) | state: data yang disimpan |
computed(...) | getter: nilai turunan dari state |
function | action: cara mengubah state |
🧪 Coba ubah: tambahkan tombol “Batal” untuk setiap buku yang sudah dipinjam, memanggil rak.hapus(b.id).
Belum ada output.
createPinia()dipasang sekali ke aplikasi denganapp.use(...), sama seperti router.useRakPinjam()dipanggil di dalamsetup. Panggilan pertama membuat store; panggilan berikutnya, di komponen mana pun, mengembalikan store yang sama.- Batas “3 buku per anggota” ditulis sekali di store, bukan di setiap komponen yang menampilkan tombol.
7.3 Satu Store, Dua Halaman
Kekuatan store terlihat saat datanya dipakai komponen berbeda di rute berbeda. Pilih buku di halaman koleksi, pindah ke halaman konfirmasi, lalu kembali: isinya tetap, karena store hidup di luar komponen yang dibuang router.
🧪 Coba ubah: pindahkan daftar dari store ke ref di dalam Koleksi. Jumlah di menu berhenti bertambah dan halaman konfirmasi selalu kosong.
Belum ada output.
Perhatikan urutannya: createPinia() dipasang sebelum mount, karena komponen root sudah memanggil useRakPinjam() saat dibuat.
7.4 storeToRefs: Membongkar Store dengan Aman
Menulis rak. di setiap tempat terasa panjang, jadi godaannya adalah membongkar store:
const rak = useRakPinjam();
const { daftar, jumlah } = rak; // SALAH: salinan nilai, tidak reaktif lagi
const { daftar, jumlah } = storeToRefs(rak); // BENAR: tetap ref yang terhubung ke store
const { tambah, hapus } = rak; // action boleh dibongkar langsung
Store adalah objek reaktif. Membongkarnya langsung mengambil nilai saat itu, sehingga tampilan tidak ikut berubah ketika store berubah. storeToRefs membungkus setiap state dan getter menjadi ref yang tetap terhubung. Action hanyalah fungsi, jadi aman dibongkar tanpa storeToRefs.
7.5 Kapan Tidak Memakai Store
Store bukan tempat untuk semua data. Data yang hanya dipakai satu komponen tetap ref lokal:
| Data | Tempat |
|---|---|
| isian form yang sedang diketik | ref/reactive lokal di komponen form |
| menu terbuka atau tertutup | ref lokal |
| daftar yang hanya tampil di satu halaman | ref lokal, diambil saat halaman dibuka |
| buku pilihan yang dipakai header dan halaman konfirmasi | store |
| anggota yang sedang masuk dan tokennya (bab 8) | store |
Aturan praktis: mulai dari ref lokal. Pindahkan ke store ketika komponen kedua yang jauh letaknya membutuhkan data yang sama.
7.6 Store dan Jalankan Ulang
Store hidup di memori halaman. Setiap kali kamu menekan Jalankan, atau pengguna memuat ulang halaman, isinya kembali ke awal. Untuk data yang harus bertahan, seperti status masuk anggota, dibutuhkan penyimpanan lain; bab 8 membahas pilihan dan risikonya, dan bab 10 membahasnya lagi untuk aplikasi produksi.
Rangkuman
- State lokal (
refdi komponen) untuk data satu komponen; store untuk data yang dipakai bersama. defineStore('id', () => { … }):ref= state,computed(...)= getter,function= action.createPinia()dipasang denganapp.usesebelummount;useNamaStore()mengembalikan store yang sama di mana pun.- Bongkar state dan getter dengan
storeToRefs; action boleh dibongkar langsung.
Bab ini tidak punya lab tersendiri: Pinia kamu latih di lab bab 8 (login dan token) dan capstone bab 9.
Berikutnya: Bab 8 memakai store untuk menyimpan anggota yang sedang masuk beserta tokennya.