Dalam artikel ini, kita akan membahas tentang menggunakan scoped slots dalam VueJS. Scoped slots memungkinkan Anda untuk menyiapkan props yang dapat diakses oleh komponen anak yang dipanggil dengan nama slot.
Penggunaan Scoped Slots
Untuk menggunakkan scoped slots, Anda perlu menambahkan atribut v-slot
ke dalam tag component. Atribut ini digunakan untuk memanggil fungsi slot dan mengirim props-nya ke dalam tag component yang dipanggil.
Contoh penggunaan scoped slots:
<MyComponent v-slot="{ text, count }">
{{ text }} {{ count }}
</MyComponent>
Dalam contoh di atas, text
dan count
adalah props yang dikirimkan oleh komponen MyComponent
. Anda dapat menggunakan destructuring untuk memisahkan props menjadi variabel yang lebih mudah digunakan.
Named Scoped Slots
Scoped slots juga dapat diberi nama dengan menggunakan atribut name
pada atribut v-slot
. Namanya slot tidak termasuk dalam props, sehingga Anda dapat menggunakan namanya sebagai nilai dari props.
Contoh penggunaan named scoped slots:
<MyComponent>
<template #header="headerProps">
{{ headerProps }}
</template>
<template #default="defaultProps">
{{ defaultProps }}
</template>
<template #footer="footerProps">
{{ footerProps }}
</template>
</MyComponent>
Dalam contoh di atas, headerProps
, defaultProps
, dan footerProps
adalah props yang dikirimkan oleh komponen MyComponent
. Anda dapat menggunakan namanya sebagai nilai dari props.
Menggunakan Named Slots dengan Default Scoped Slot
Jika Anda ingin menggunakan named slots dengan default scoped slot, Anda perlu menggunakan tag <template>
untuk default slot. Atribut v-slot
tidak dapat digunakan pada tag component yang tidak memiliki label slot.
Contoh penggunaan named slots dengan default scoped slot:
<!-- <MyComponent> template -->
<div>
<slot :message="hello"></slot>
<slot name="footer" />
</div>
<!-- This template won't compile -->
<MyComponent v-slot="{ message }">
<p>{{ message }}</p>
<template #footer>
<!-- message belongs to the default slot, and is not available here -->
<p>{{ message }}</p>
</template>
</MyComponent>
Dalam contoh di atas, Anda tidak dapat mengakses message
prop dalam tag <template #footer>
karena props tersebut hanya tersedia untuk default scoped slot.
Contoh Penggunaan Fancy List
Fancy list adalah contoh penggunaan scoped slots yang lebih lanjut. Misalnya, kita memiliki komponen <FancyList>
yang merenderkan daftar item – komponen ini dapat menggabungkan logika untuk memuat data jarak jauh, menggunakan data untuk menampilkan daftar, atau bahkan fitur seperti pagination atau infinite scrolling.
Contoh penggunaan fancy list:
<FancyList :api-url="url" :per-page="10">
<template #item="{ body, username, likes }">
<div class="item">
<p>{{ body }}</p>
<p>by {{ username }} | {{ likes }} likes</p>
</div>
</template>
</FancyList>
Dalam contoh di atas, kita dapat menggunakan scoped slots untuk menyiapkan props yang digunakan oleh komponen FancyList
.
Renderless Components
Components renderless adalah komponen-komponen yang hanya menggabungkan logika dan tidak merenderkan apapun. Visual output-nya sepenuhnya didelegasikan ke komponen induk dengan scoped slots.
Contoh penggunaan renderless components:
<MouseTracker v-slot="{ x, y }">
Mouse is at: {{ x }}, {{ y }}
</MouseTracker>
Dalam contoh di atas, kita memiliki komponen MouseTracker
yang hanya menggabungkan logika untuk memantau posisi mouse dan tidak merenderkan apapun. Visual output-nya sepenuhnya didelegasikan ke komponen induk dengan scoped slots.
Dengan demikian, scoped slots memungkinkan Anda untuk menyiapkan props yang dapat diakses oleh komponen anak yang dipanggil dengan nama slot. Namanya slot tidak termasuk dalam props, sehingga Anda dapat menggunakan namanya sebagai nilai dari props.