Provide & Inject
Berbagi data antar komponen tanpa prop drilling dengan provide dan inject, nilai default, mengirim fungsi pengubah, readonly, dan key berbasis Symbol.
Masalah: prop drilling
Bayangkan tema aplikasi (terang/gelap) dibutuhkan oleh tombol yang terkubur lima tingkat di dalam komponen. Dengan props, setiap komponen perantara harus meneruskan tema padahal ia sendiri tidak memakainya. Ini disebut prop drilling — melelahkan dan rawan salah.
provide / inject memecahkannya: sebuah komponen leluhur "menyediakan" (provide) data, dan keturunan mana pun — sedalam apa pun — dapat "mengambilnya" (inject).
Dasar pemakaian
<!-- Leluhur (App.vue) -->
<script setup>
import { ref, provide } from 'vue'
const tema = ref('terang')
function gantiTema() {
tema.value = tema.value === 'terang' ? 'gelap' : 'terang'
}
provide('tema', tema)
provide('gantiTema', gantiTema)
</script>
<!-- Keturunan (Panel.vue, di tingkat berapa pun) -->
<script setup>
import { inject } from 'vue'
const tema = inject('tema')
const gantiTema = inject('gantiTema')
</script>
<template>
<button @click="gantiTema">Tema: {{ tema }}</button>
</template>
Karena yang disediakan adalah ref, perubahan tetap reaktif di semua penerima.
Nilai default
const tema = inject('tema', 'terang') // default statis
const config = inject('config', () => ({ a: 1 }), true) // default berupa fungsi pabrik
Tanpa default dan tanpa provider, Vue memberi peringatan "injection not found".
Praktik terbaik: sediakan fungsi pengubah di tempat yang sama
Letakkan logika perubahan state di komponen yang menyediakan dan kirim fungsinya (seperti gantiTema). Dengan begitu aliran perubahan tetap mudah dilacak: hanya satu tempat yang boleh mengubah tema. Untuk memastikan penerima tidak mengubah langsung, bungkus dengan readonly:
import { readonly } from 'vue'
provide('tema', readonly(tema))
Provide level aplikasi
// main.js
app.provide('namaSitus', 'KelasIT') // tersedia untuk semua komponen
Key berbasis Symbol (proyek besar)
// keys.js
export const KEY_TEMA = Symbol('tema')
provide(KEY_TEMA, tema)
const tema = inject(KEY_TEMA)
Symbol mencegah tabrakan nama antar pustaka dan memudahkan autocomplete saat memakai TypeScript.
Kapan memakai apa?
| Kebutuhan | Alat |
|---|---|
| Anak langsung perlu data | Props |
| Banyak tingkat, data "ambient" (tema, bahasa, pengguna) | provide/inject |
| Data global yang diakses banyak halaman, perlu debugging | Pinia (bab 22) |
Kesalahan umum
- Menyediakan nilai biasa (bukan ref) lalu berharap reaktif — perubahan tidak terdeteksi.
- Menyalahgunakan provide/inject untuk semua data sehingga alur data sulit dilacak.
- Memanggil
injectdi luarsetup(di callback atau event).