Image description
slot tanpa daftar
Cara Menggunakan Slot Bersarang di Vue (termasuk slot scoped)

Perkenalan

Saya baru-baru ini menemukan cara mengimplementasikan slot bersarang secara rekursif, termasuk cara melakukannya dengan slot scoped. Semuanya bermula ketika saya ingin melihat apakah saya bisa membangun komponen yang mereplikasi direktif v-for, tetapi hanya menggunakan template.

Untuk mempersingkat cerita: saya berhasil.

Merender daftar tanpa menggunakan direktif v-for atau fungsi render. Mendukung slot scoped juga...

Dan ya, ini mendukung slot dan slot scoped — dan bisa dibuat untuk mendukung slot bernama juga.

Kita bisa menggunakannya seperti ini:

<template> <div> <!-- Daftar biasa --> <v-for :list="list" /> <!-- Daftar dengan item tebal --> <v-for :list="list"> <template v-slot="{ item }"> <strong>{{ item }}</strong> </template> </v-for> </div></template>

Yang pertama akan mencetak daftar item secara normal, sedangkan yang kedua akan membungkus setiap item dalam tag <strong>. Ini bukan komponen yang sangat berguna, tapi saya suka bereksperimen untuk belajar lebih banyak.

Perulangan tanpa loop

Biasanya kita akan menggunakan direktif v-for untuk merender daftar elemen atau komponen. Tapi kita ingin menghilangkannya sepenuhnya. Jadi, bagaimana cara merender daftar item tanpa menggunakan perulangan? Jawabannya: rekursi. Kita bisa menggunakan rekursi untuk merepresentasikan daftar item.

Merepresentasikan daftar secara rekursif

Salah satu mata kuliah favorit saya di universitas adalah Programming Language Concepts. Bagian yang paling menarik adalah menjelajahi pemrograman fungsional dan logika, serta melihat perbedaannya dengan pemrograman imperatif. Dari mata kuliah itu saya belajar bahwa daftar bisa direpresentasikan secara rekursif. Alih-alih menggunakan array, setiap daftar adalah sebuah nilai (kepala) dan daftar lainnya (ekor).

[head, tail]

Jika ingin merepresentasikan daftar [1, 2, 3], maka akan menjadi:

[1, [2, [3, null]]]

Kita harus mengakhiri daftar dengan null (atau array kosong). Konsep ini bisa diterapkan ke komponen kita dengan menumpuk komponen secara rekursif untuk merepresentasikan daftar. Hasil render akan seperti ini:

<div> 1 <div> 2 <div> 3 </div> </div></div>

Tentu saja ini tidak persis sama dengan yang dihasilkan v-for, tapi itulah inti latihan ini.

Membangun komponen

Pertama, kita akan merender daftar item secara rekursif. Setelah itu berhasil, kita akan menambahkan slot.

Menggunakan rekursi untuk merender daftar

Alih-alih menggunakan daftar rekursif, kita akan bekerja dengan array biasa: [1, 2, 3]. Kita harus menangani dua kasus:

  1. Kasus dasar – merender item pertama dalam daftar.
  2. Kasus rekursif – merender item, lalu daftar berikutnya.

Kirim [1, 2, 3] ke v-for:

<template> <v-for :list="[1, 2, 3]" /></template>

Kita ambil item pertama (1) dan tampilkan:

<template> <div> {{ list[0] }} </div></template>

Tapi kita tidak bisa berhenti di situ. Kita juga perlu merender sisa daftar:

<template> <div> {{ list[0] }} <v-for :list="list(1)" /> </div></template>

Dengan memotong item pertama dan mengirimkan array baru, kita mencetak 1, lalu kirim [2, 3] ke v-for berikutnya, dan seterusnya. Untuk menghentikan rekursi, tambahkan kondisi:

<template> <div> {{ list[0] }} <v-for v-if="list > 1" :list="list(1)" /> </div></template>

Dengan begitu, rekursi berhenti saat item habis.

Slot bersarang secara rekursif

Kita ingin komponen bekerja dengan slot scoped agar bisa menyesuaikan tampilan setiap item:

<template> <v-for :list="list"> <template v-slot="{ item }"> <strong>{{ item }}</strong> </template> </v-for></template>

Menumpuk slot

Konsep menumpuk slot mirip dengan slot biasa. Misalkan ada tiga komponen: Parent, Child, dan Grandchild. Kita ingin mengirim konten dari Parent ke Grandchild melalui Child.

// Parent<template> <Child> <span>Never gonna give you up</span> </Child></template>

Komponen Child menghubungkan slot dari Parent ke Grandchild:

// Child<template> <Grandchild> <slot /> </Grandchild></template>

Dan Grandchild merender slot tersebut:

// Grandchild<template> <div> <slot /> </div></template>

Menambahkan slot scoped

Untuk slot scoped, kita juga harus mengirim data scoped. Implementasi pada komponen v-for menjadi:

<template> <div> <slot v-bind:item="list[0]"> <!-- Default --> {{ list[0] }} </slot> <v-for v-if="list > 1" :list="list(1)" > <!-- Kirim slot scoped secara rekursif --> <template v-slot="{ item }"> <slot v-bind:item="item" /> </template> </v-for> </div></template>

Jika tidak ada slot yang disediakan, kita menggunakan nilai default (list[0]). Jika ada slot, item akan dikirim ke parent melalui scope slot. Di kasus rekursif, slot dikirim ke v-for berikutnya dan item diteruskan ke atas.

Sekarang kita memiliki komponen yang meniru (kurang lebih) v-for hanya menggunakan template!

Kesimpulan

Kita telah melalui jalan panjang dan berliku, namun sekarang kita telah melihat cara membuat komponen yang mereplikasi v-for hanya dengan template. Kita membahas:

  • Representasi daftar secara rekursif
  • Komponen rekursif
  • Slot bersarang dan slot scoped bersarang (atau slot rekursif)
© 2026 - Semua hak dilindungi undang-undang. PT dengan modal Rp 10.000.000.000. Jl. Jend. Sudirman Kav. 52-53, Jakarta Selatan 12190