Gdy zaczynałem naukę Vue, sloty wydawały mi się trudne w użyciu i nie do końca wiedziałem dlaczego miałbym ich użyć? Szybko więc się odbiłem od tematu i pisałem kod nawet nie rozważając ich użycia. Zdecydowanie był to błąd i dopiero po jakimś czasie zrozumiałem jak ogromny potencjał tkwi w wykorzystaniu slotów. Podzielę się trochę wiedzą na ich temat oraz tym jak z nich korzystam.
Zakładam, że ktoś kto będzie czytał ten post będzie już znał podstawy Vue i z tego względu też nie chcę skupiać się w tym poście na objaśnianiu podstawowych pojęć związanych z tym frameworkiem. Sloty ogólne rzecz biorąc są mechanizmem, który pozwala nam na tworzenie komponentów wielokrotnego użytku. Mechanizm ten na pewno ułatwia korzystanie z pewnej znanej programistom reguły DRY( Don’t Repeat Yourself). Cały trik polega na tym że sloty dają nam możliwość umieszczenia lub zmiany treści jeżeli komponent dziecka zaimportujemy do rodzica. Sloty w Vue.js możemy rozumieć jako miejsce w ktorym umieszczamy nową treść lub pozostawiamy tą domyślnie zadeklarowaną.
Child.vue
<template>
<div>
<p>Hej, jestem komponentem dziecka!</p>
<slot />
</div>
</template>
app.vue
<template>
<div>
<child>
<p>A ja jestem treścią dodaną w rodzicu!</p>
</child>
</div> </template
>;
<script>
import Child from "./Child.vue";
export default {
components: {
child: Child
}
};
</script>
Jak widać powyżej w rodzicu możemy dodać dowolną treść czego efektem ostatecznym będzie wyrenderowanie:
<div>
<p>Hej, jestem komponentem dziecka!</p>
<p>A ja jestem treścią dodaną w rodzicu!</p>
</div>
Tutaj też warto nadmienić, że możemy użyć nie jeden a kilka razy slotów w naszym komponencie dziecka, dzięki czemu będziemy mogli na przykład za pomocą mechanizmu wyszczególnić header, footer i section. Jednakże aby użyć więcej niż jednego slotu w komponencie musimy każdemu poszczególnemu slotowi nadać nazwę do której będziemy się odnosili.
Child.vue
<template>
<div>
<header>
<slot name="”header”"><h2>Tytuł</h2></slot>
</header>
<section class="”slot__body”">
<slot name="”body”"> </slot>
</section>
<footer>
<slot name="”" footer”> <p>standardowa stopka</p></slot>
</footer>
</div> </template
>;
App.vue
<template>
<child>
<template v-slot:header>
<h2>Nowy tytuł nadany przez rodzica</h2>
</template>
<template v-slot:body>
<p>Treść, która zostanie dodana do section dziecka</p>
</template>
<template v-slot:footer>
<p>zmiana standardowej treści stopki na własną</p>
</template>
</child>
</template>
Istnieje też coś co nazywamy Scoped slots. Wymieniony rodzaj slotów jest szczególnie przydatny jeżeli chcielibyśmy przekazać dane z komponentu dziecka posiadajcego sloty do rodzica.
Child.vue
<template>
<span>
<slot v-bind:car="”car”">
{{ car.type}}
</slot>
</span>
</template>
<script>
export default {
data () {
return {
car: ...
}
}
}
</script>
app.vue
<template>
<child>
<template v-slot:default="slotProps">
{{ slotProps.car.type }}
</template>
</child>
</template>
Sloty są dla mnie mechanizmem, który pozwala mi na przykład napisać komponent modal, który wykorzystam wielokrotnie na wiele sposobów. Oczywiście też można spróbować zastosować sloty w przypadku samego layoutu. Czytałem ostatnio, że biblioteki UI korzystają z tego mechanizmu by na przykład stworzyć komponent nawigacji? Sloty również przydają się w przypadku pisania renderless components w Vue. Na ten temat postaram się jeszcze coś napisać niebawem. Tutaj można znaleźć nieco więcej informacji o samym renderless components. Tutaj zaś można znaleźć informacje na temat samych slotów.