Miniatura artykułu

Vue 3 - slots

9 minut

Skopiuj link

Data publikacji: 11/19/2023, 7:24:38

Ostatnia aktualizacja: 4/19/2024

Wprowadzenie

Temat dzisiejszego artykułu jest stosunkowo prosty, lecz niezwykle przydatny. Poznasz slots, jest to mechanizm umożliwiający wstawianie do komponentów określonej zawartości, możemy zastosować sloty na kilka sposobów. Skupiam się tutaj tylko i wyłącznie na Vue w wersji 3 i nie będę prezentować kodu, ani zastosowania z wersji poprzednich.

Slots

Cała koncepcja używania slotów polega na tym, że możemy przekazywać zawartość, która ma zostać wyrenderowana w komponencie, jest to naprawdę proste w przypadku używania domyślnego. Możesz to porównać do tego, jak umieszczasz tekst między tagami HTML, sloty działają podobnie, tyle że to my musimy określić miejsce wystąpienia przekazanej zawartości. Nie ma chyba prostszego komponentu, aby to pokazać, jak przycisk, a dzięki slots będziemy do niego przekazywać tekst, który się w nim wyświetli.

Jak widzisz jest to bardzo prosty mechanizm, to co przekażesz teraz, pomiędzy tagami stworzonego komponentu, wyląduje w miejscu określenia slotu, a tak naprawdę stanie się dziećmi tego komponentu.

Istnieje też sposób, aby już na początku określić zawartość z możliwością jej podmiany, dla przykładu stwórzmy teraz przycisk, który domyślnie będzie posiadał tekst "Potwierdź", ale nic nie stoi na przeszkodzie, aby nadpisać mu tą zawartość, przekazując inną treść.

Dzięki takiemu zastosowaniu, możemy domyślnie użyć takiego przycisku z określonym wcześniej tekstem, bez przekazywania jakiejkolwiek zawartości, a gdy zaistnieje taka potrzeba, zmienić ją na inną.

Named slots

Ktoś już na pewno przytomnie zauważył, że wcześniej wspomniałem o określeniu miejsca, w którym umieszczamy nasz slot, bo o ile nic nie stoi na przeszkodzie, aby wewnątrz komponentu umieszczać dowolną inną strukturę, to nadal i tak mieliśmy do dyspozycji tylko jeden slot, teraz poznasz named slots, które umożliwią przekazanie zawartości w kilka różnych miejsc. Posłużę się przykładem klasycznego dialogu, który będzie posiadać trzy takie sloty: header, main oraz footer. Chcąc nazwać slot musimy określić ich nazwy tworząc komponent i każdemu slotowi przydzielić jego własną nazwę poprzez name, następnie chcąc przekazać zawartość do konkretnego slotu, używamy template z odpowiednią nazwą poprzez #nazwa_slota dodam też, że jest to skrót od v-slot:nazwa_slota, także oba te zapisy będą miały ten sam efekt.

Pamiętaj również, że nic nie stoi na przeszkodzie, aby wewnątrz komponentu, w strukturze ze slotami, również dodawać inne, stałe i określone z góry przez Ciebie elementy. Na przykład, jeśli Twój komponent dialogu zawsze będzie miał taką samą ikonę do jego zamykania (którą teraz przekazujemy poprzez slot), możesz ją przełożyć do samego komponentu. Nie sugeruj się tymi dodatkowymi komponentami, których tam używam, mają służyć jedynie w celach dydaktycznych, aby zobrazować Ci, jak można przykładowo z tego skorzystać. Ilustracja (biorąc pod uwagę oczywiście odpowiednio dodane style), prezentuje dialog, który mógłby wyglądać mniej więcej w ten sposób:

Tak mógłby wyglądać przykładowy dialog.

Tak mógłby wyglądać przykładowy dialog.

Podział na sloty.

Podział na sloty.

Na zakończenie tej sekcji dodam, że nazwy slotów mogą być również dynamiczne, zarówno te standardowe z użyciem v-slot, jak i poprzez skrót #.

Scoped slots

Jest to zdecydowanie bardziej doświadczony sposób używania slotów, niemniej jednak nie jest to tak trudne, jak mogłoby się wydawać. Scoped slots służą też do przekazywania szablonów z komponentu rodzica do komponentu dziecka, ale przy jednoczesnym umożliwieniu dostępu do danych z komponentu dziecka. To pozwala na dużą elastyczność w tworzeniu interfejsów użytkownika, ponieważ możemy definiować wygląd i strukturę treści w komponencie rodzica, a jednocześnie korzystać z danych dostępnych w komponencie dziecka.

W skrócie, idea polega na tym, że komponent dziecka oferuje slot, który jest "wypełniany" przez komponent rodzica. Jednak to, co jest unikalne dla scoped slots, to fakt, że rodzic może korzystać z danych dostarczonych przez komponent dziecka podczas "wypełniania" tego slotu. Idealnym przykładem wydaje się być komponent listy.

W ten sposób utworzyliśmy komponent listy, któremu przekazujemy poprzez rodzica, strukturę każdego z jej elementów, zobacz jak to pozwala dopasować taki komponent w wielu miejscach, gdyż nie zawsze możesz chcieć prezentować np. autora, wystarczy że używając tego samego komponentu po prostu nie przekażesz tego w strukturze do slota. Możesz w ten sposób także nadać własne style dla każdego z wyświetlanych tam elementów, mało tego, możesz dodać logikę, którą często zawierają listingi, jak np. infinite scroll, pull refresh czy paginacja i umieścić w tym komponencie, a jedynie przekazywać, jak dany element listy ma zostać zaprezentowany, jest to bardzo potężny mechanizm.

Tłumacząc jeszcze co dokładnie dzieje się w kodzie, to tam gdzie implementujemy CustomList, przekazujemy do komponentu poprzez props listę książek, odpowiednio listujemy z wykorzystaniem v-for, lecz już nie tworzymy tam układu każdego z elementów listy, zamiast tego umieszczamy slota, który ma name określony na book oraz tak naprawdę nic innego, jak swojego propsa book-details, do którego zostaje przekazany pojedynczy obiekt książki z tej listy.

To co dzieje się podczas używania tego komponentu, to oczywiście przekazanie listy, która ma zostać wyrenderowana oraz przekazanie do template o nazwie naszego slota (book - pamiętasz? przed chwilą w komponencie daliśmy taką nazwę slotowi), strukturę jaka ma poszczególny element zawierać. Zatem, skąd bierzemy informacje o danej książce? Ano wystarczy po nazwie naszego slota odebrać propsy, które przekazaliśmy do slota implementując komponent, w naszym przypadku był to tylko jeden prop book-details, ale nic nie stoi na przeszkodzie, by przekazać ich więcej. W każdym razie i tak odbieramy wszystkie propsy w jednym obiekcie w tym przypadku: #book="slotProps", gdzie to znajdują się wszystkie przekazane przez nas propsy, dostajemy się do nich normalnie po . (jak to w obiektach). Nazwa slotProps jest arbitralna i możesz użyć tu dowolnej nazwy, która Ci odpowiada oczywiście z zachowaniem konwencji nazewniczej. Specjalnie też, zastosowałem tutaj prop o nazwie dwuczłonowej (book-details), aby pokazać, jak odczytać taką właściwość w obiekcie (bookDetails), stosując camelCase.

Podsumowanie

Mam nadzieję, że wystarczająco zrozumiale przedstawiłem Ci temat slotów w Vue 3, jednak gdyby jeszcze było coś niejasnego to zachęcam Cię najpierw do przeczytania artykułu ponownie, a później koniecznie sprawdź to w praktyce, spróbuj przekleić podane tu przykłady i pozmieniać według własnych potrzeb, wtedy najlepiej przyswoisz wiedzę. Polecam skorzystać w tym celu z playgrounda Vue, jest wygodny intuicyjny i przejrzysty, nie potrzebujesz nic konfigurować, piszesz kod i widzisz rezultat. Zawsze możesz też zadać pytanie w komentarzach pod tym artykułem, chętnie odpowiem.

Avatar: Maciej Mikołajczak

Front-end Developer

Maciej Mikołajczak

mcj.mikolajczak@gmail.com

Podziel się na

Dodaj komentarz

Komentarze (0)

Brak komentarzy