Vue'da slotlar nima: default, nomlangan va scoped?

MiddleVue.js #vue #slots #templates

Savol

Vue'da slotlar nima, default-slot, nomlangan slotlar va scoped-slotlar bir-biridan nimasi bilan farq qiladi?

Qisqa javob

Slotlar — ota komponentga bola komponent ichiga (faqat ma'lumot emas) razmetka uzatish imkonini beruvchi mexanizm bo'lib, uni qayerga qo'yishni bola komponentning o'zi hal qiladi. Default-slot — asosiy tarkib uchun bitta nomsiz slot; nomlangan slotlar shablonning turli joylariga bir nechta mustaqil razmetka bo'lagini uzatish imkonini beradi; scoped-slotlar esa qo'shimcha ravishda bola komponentga ota komponent render qiladigan slot tarkibiga o'z ma'lumotlarini qaytarib uzatish imkonini beradi.

Batafsil javob

Agar props ma'lumot, events esa hodisalar haqida signal uzatsa, slotlar razmetkani uzatadi. Bola komponent o'z shablonida <slot> joyini e'lon qiladi — ota komponent tomonidan komponentning ochuvchi va yopuvchi teglari orasida uzatilgan tarkib shu yerga joylashtiriladi.

  • Default-slot. Bola komponentdagi <slot></slot> — ota komponent tarkibni teglar orasiga oddiygina yozadi: <Card>Matn</Card>. Agar ota komponent hech narsa uzatmasa, <slot>Standart tarkib</slot> ichida standart tarkibni ko'rsatish mumkin.
  • Nomlangan slotlar (named slots). Bir nechta mustaqil joylashtirish joyi kerak bo'lganda (masalan, kartaning shapkasi/tanasi/podvali), slotlar nomlanadi: <slot name="header" />. Ota komponent qaysi razmetka qayerga borishini <template #header> orqali ko'rsatadi.
  • Scoped-slotlar. Odatda ma'lumot ota komponentdan slot tarkibiga oqadi, lekin ba'zan aynan bola komponent maxsus ko'rinishda ko'rsatilishi kerak bo'lgan ma'lumotlarga egalik qiladi (masalan, ro'yxat komponenti iteratsiyaning joriy elementini biladi, uni qanday chizishni esa ota komponent hal qiladi). Bola komponent ma'lumotlarni <slot>dagi atributlar orqali uzatadi: <slot :item="item" />. Ota komponent ularni slot-props obyektini destrukturizatsiya qilib, <template #default="{ item }"> orqali oladi.

Slotlar — strukturasi va logikasi bir xil bo'lib, har safar konkret tarkibi turlicha bo'ladigan qayta ishlatiladigan, razmetkasi moslashuvchan komponentlar (modallar, kartalar, ro'yxatlar, layout'lar) yozishning asosiy vositasi.

Misol

<!-- BaseCard.vue: nomlangan + scoped slotlar -->
<script setup>
defineProps({
  items: { type: Array, required: true }
})
</script>

<template>
  <div class="card">
    <header class="card__header">
      <!-- standart tarkibli nomlangan slot -->
      <slot name="header">Sarlavhasiz</slot>
    </header>

    <ul class="card__body">
      <!-- scoped slot: bola komponent item va index'ni tashqariga uzatadi -->
      <li v-for="(item, index) in items" :key="item.id">
        <slot :item="item" :index="index">
          {{ item.name }} <!-- standart xatti-harakat -->
        </slot>
      </li>
    </ul>
  </div>
</template>
<!-- Parent.vue -->
<script setup>
import BaseCard from './BaseCard.vue'

const users = [
  { id: 1, name: 'Alice', active: true },
  { id: 2, name: 'Bob', active: false }
]
</script>

<template>
  <BaseCard :items="users">
    <template #header>
      <h2>Foydalanuvchilar ro'yxati</h2>
    </template>

    <!-- scoped-slot: bola komponentdan item'ni olamiz -->
    <template #default="{ item }">
      <strong :class="{ online: item.active }">{{ item.name }}</strong>
    </template>
  </BaseCard>
</template>

Qo'shimcha savollar

  • v-slot (#) oddiy v-binddan nimasi bilan farq qiladi va nega slotlarning o'z ko'rinish sohasi bor?
  • Ota komponent konkret slotga tarkib uzatganini qanday tekshirish mumkin ($slots)?
  • Qaysi holatda scoped-slot o'rniga oddiy prop-funksiya (render prop) ishlatgan ma'qul?