Techniki Zaawansowane
5 godz. 11 min · Vue.js · Full-stack i Programowanie
Piotr PalarzWeb DeveloperKurs, który masz przed sobą, to kontynuacja wydanego wcześniej kursu Vue.js od Podstaw. W pierwszym kursie omówione zostały najważniejsze koncepcje pracy z Vue, a w tym materiale poruszamy już bardziej zaawansowane tematy. Przede wszystkim skupimy się na pracy z użyciem nowoczesnego workflow, co da nam niezwykłą swobodę tworzenia aplikacji internetowych. Jeśli zatem znasz już podstawy pracy z tym frameworkiem i chcesz wskoczyć na kolejny poziom wtajemniczenia, ten kurs jest zdecydowanie dla Ciebie. A co znajdziesz w materiale?
Na początku zobaczysz, jak szybko tworzyć pliki startowe do nowej aplikacji z użyciem narzędzia vue-cli. Omówimy możliwość dzielenia kodu na wiele plików, tworzenia szablonów, a także wykorzystywania bezpośrednio funkcji renderującej, do której zamieniane są na etapie builda wszystkie szablony.Zobaczysz również czym są i jak pracować z komponentami funkcyjnymi i tzw. mixinami, które pozwolą reużywać raz napisany fragment kodu.
Przepływ informacji to bardzo ważny temat w każdej aplikacji internetowej. Vue oferuje kilka sposobów na to, aby komponenty mogły się ze sobą komunikować. Ich omówienie zaczniemy od najprostszych technik, które świetnie sprawdzają się w wielu przypadkach. Następnie rozszerzymy możliwości instancji Vue w ten sposób, aby wszystkie komponenty miały dostęp do scentralizowanego miejsca, gdzie przechowywany będzie stan aplikacji.Tam jednak, gdzie aplikacja wymaga zarządzania większą ilością danych jednocześnie, powyższe techniki mogą być niewystarczające. Z tego powodu, podobnie jak w innych frameworkach, Vue posiada oficjalny wzorzec oraz bibliotekę do zarządzania stanem aplikacji. Rozwiązanie to nazywa się VueX i w kursie zostanie ono dokładnie omówione. Zobaczysz zatem jak skonfigurować tzw. store, jak przechowywać w nim dane, jak je wyświetlać w widokach, aktualizować za pomocą tzw. mutacji czy pracować z nimi wykorzystując akcje. Przekonasz się, że początkowa większa ilość pracy, aby wszystko skonfigurować, w pewnym momencie zaczyna się opłacać.
Tworzenie nowoczesnych aplikacji typu SPA (Single Page Application) nie może się obejść bez zmian widoków. Dobrą praktyką jest, aby wraz z takimi zmianami, aktualizowany był również pasek adresu. Wykonanie takiego zadania umożliwiają nam tzw. routery. Vue posiada oficjalny dodatek o nazwie vue-router, który w tym kursie dokładnie omówimy.Zobaczysz jak dołączyć router do swojego projektu, a także jak konfigurować ścieżki. Poruszymy tematy takie jak generowanie odnośników, dynamiczne parametry, tworzenie zagnieżdżonych ścieżek czy nawigacja z poziomu kodu JavaScript. Dowiesz się również, jak tworzyć tzw. guardy, które umożliwią lub zablokują możliwość wyświetlania wybranego widoku, np. w zależności od tego czy użytkownik jest aktualnie zalogowany.
Trzecim, po zarządzaniu stanem aplikacji i wykorzystaniu routingu, komponentem, który niezbędny jest do tworzenia aplikacji napędzanych danymi, jest możliwość wysyłania zapytań HTTP.Tę czynność umożliwi nam bardzo popularna, acz niezależna od Vue biblioteka axios. Zobaczysz jak za jej pomocą pobierać i wysyłać dane. Aby jednak jak najwygodniej pracować z tym rozwiązaniem, połączymy axios z Vue, udostępniając tak naprawdę jej metody wewnątrz każdego komponentu.
W jednym z rozdziałów kursu podejmiemy temat walidacji formularzy. Zobaczysz jak z pomocą popularnego pluginu dla Vue, robić to w bardzo prosty sposób.Omówimy różne funkcje walidujące, które umożliwią sprawdzenie poprawności pól tekstowych, radio czy checkboxów. Zobaczysz jak w łatwy sposób wyświetlać komunikaty o błędach i warunkowo zmieniać wygląd pól. Nie zabraknie również informacji o asynchronicznej walidacji, która pozwoli nam na żywo sprawdzać czy wpisany adres email jest dostępny czy też nie.
Kurs ten oczywiście to nie tylko niezbędna teoria, ale także praktyczne przykłady. Aby jak najlepiej poznać omawiane techniki, wykorzystamy je do stworzenia ciekawych aplikacji.Pierwszą z nich będzie konfigurator produktu, który umożliwi użytkownikowi wybór podzespołów zamawianego komputera. Każdy taki wybór będzie wpływał na końcową cenę, która będzie na bieżąco aktualizowana. Po wybraniu wszystkich opcji, dane prześlemy na serwer. To projekt który pokaże Ci jak przechowywać dane z użyciem VueX, a także jak na ich podstawie wyświetlić widok i napisać logikę.Innym projektem, który wykonamy, będzie Quiz. To aplikacja, gdzie użytkownik odpowiadał będzie na serię pytań pobranych z serwera, a do wyboru będą 3 odpowiedzi. Po przejściu przez wszystkie pytania, wyślemy do serwera zapytanie, a ten w zamian zwróci nam listę poprawnych odpowiedzi. Dzięki temu pokażemy użytkownikowi, gdzie miał rację, a gdzie popełnił błąd. Aplikacja ta wykorzystywać będzie wszystkie najważniejsze techniki, tj. VueX, routing, a także Ajax.
Kurs ten jest dla wszystkich osób, które czują się już swobodnie w pracy z frameworkiem Vue. Jeśli zatem masz już solidną wiedzę podstawową lub przerobiłeś kurs Vue.js od Podstaw, to zdecydowanie jesteś gotów na poszerzenie swoich umiejętnośći w pracy z tym frameworkiem. Co ważne, doświadczenie w pracy z innymi frameworkami JavaScript nie jest tutaj wymagane, a jedyne co będzie bardzo pomocne, to znajomość nowej składni EcmaScript 6.
Vue.js 2.x.x
W tej lekcji zajmiemy się, tak jak wspomniałem przygotowaniem widoków, tak żeby one z tych dynamicznych
danych były renderowane. Pominiemy sobie
na razie ten widok, który widzisz, ale stworzymy również dla niego osobny komponent, więc ja proponuję
od tego zacząć, to co jest niepotrzebne w tym layoucie.
Możemy jakby od razu sobie wyciągnąć gdzieś indziej, to nam się przyda w jednej z kolejnych lekcji.
Czyli skoro mamy to tutaj, może to v-else usunę, bo to później nie będzie potrzebne.
Ja sobie to w całości wycinam i będę chciał w katalogu 40 w src components utworzyć komponent o nazwie
Summary.vue.
I tutaj stworzymy sobie ten komponent wstawiając całą jego treść.
Tak jak wspomniałem, będziemy go dynamicznie uzupełniać
dopiero w ostatniej lekcji, natomiast te style, które się z nim wiązały również możemy tutaj przykopiować,
czyli cały ten blok.
Mam nadzieję, że pracujesz razem ze mną.
Mamy sporo do zrobienia, więc w zasadzie dobrze by było żebyś był ze mną na bieżąco, bo za chwilę może
się tutaj zrobić trochę zbyt skomplikowanie.
Niemniej jednak wyciągnęliśmy sobie ten komponent i na razie nic innego z nim nie będziemy robić, ale oczyszczamy
sobie ten kod, bo wyobraźmy sobie, że po prostu designer lub my sami, przygotowaliśmy najpierw layout
i teraz chcemy to ładnie podzielić.
Ok.
Druga rzecz, którą moglibyśmy stąd wyciągnąć, to jest w zasadzie całe to question.
Fajnie by było wstawić tutaj może komponent Question, w ten sposób, więc teraz go utworzymy katalog 40
src components i nazwiemy go Question, ok.
Ten kod również tutaj wkleję.
On będzie musiał być dynamiczny, ale tym się zajmiemy za sekundę. Zajmijmy się jeszcze stylami, żeby po
prostu nie zapomnieć.
Czyli to co mamy tutaj moglibyśmy sobie również wstawić do tych styli, więc te style po prostu będą
dla każdego komponentu,
jak widzisz, dostosowane. OK.
Teraz oczywiście, żeby to wszystko mogło w ogóle działać, to będziemy musieli sobie questions, z którego
tutaj skorzystaliśmy zaimportować, a więc import Question from
i tutaj jesteśmy w aplikacji Quiz, więc ten sam katalog.
I musimy to jeszcze dodać do components.
OK.
Zobaczmy zatem czy to w ogóle nam się wyświetla.
Czy mamy jakieś błędy.
Okej, nic tutaj się specjalnego nie dzieje, ale to przez ten v-if
i tutaj mamy false.
Jeśli to zmienimy na true, to już nam się to ładnie wyświetla.
Natomiast ja będę chciał to wyświetlać warunkowo pod warunkiem, że mamy już pobrane AJAX'em
wszystkie pytania, czyli jeżeli przejdziemy do store tutaj na początku jest null.
Natomiast jeżeli już nie będzie noll, tylko będziemy tutaj mieli tablicę, to wtedy chcę to wyświetlić.
Więc będąc tutaj w naszym quizie będę chciał w computed dodać sobie coś takiego jak questions i tutaj zwrócimy return this
store state questions, ok i dzięki temu będę mógł tutaj napisać qestions i zobaczmy wygląda na to, że
wszystko działa poprawnie.
Ok.
Zatem do tego pytania, do wewnątrz chciałbym przekazywać aktualne pytania i utworzyliśmy sobie coś takiego
jak currentQuestions.
Zaczynamy od pierwszego, więc chciałbym utworzyć taki getter, który nam to również będzie tutaj podawał,
bo chciałbym zrobić taki prop tutaj jak question i mu przekazać właśnie te dane, czyli musimy sobie tutaj utworzyć
computed,
Ale zanim to zrobimy, nie zapomnimy również przyjmować prop.
Czyli przyjmiemy sobie w props coś takiego jak question.
Ok.
I tutaj w computed będziemy chcieli to zwrócić.
Czyli aktualne pytanie i możemy to zrobić w dosyć prosty sposób, skoro mamy już computed property questions, to
możemy napisać return this.questions. To będzie tablica i będę chciał zwrócić ten element tablicy, który jest
pod indeksem właśnie tutaj currentQuestion. Jeszcze tylko jak mamy 1, to mamy od tego 1 i zwrócimy pierwszy
element, czyli 0 w tablicy,
jak zapewne wiesz.
Więc tutaj się odwołamy do this store. Następnie state currentQuestion minus 1, OK.
To nam powinno zwracać aktualne pytanie, czyli na razie pierwszy element z tablicy. Powinno to być przekazywane
w to miejsce i powinno wpadać tutaj do question.
Więc zastanówmy się jak moglibyśmy z tego korzystać, w ogóle czym jest to question, jeżeli sobie tutaj podejrzymy,
jedno pojedyncze pytanie to będzie taki obiekt.
Czyli ma on coś takiego jak question i answers.
I właśnie z tego question będziemy chcieli skorzystać w tym miejscu, czyli question.question w naszym
przypadku, ok.
Widzimy, że to działa rzeczywiście, mamy pierwsze pytanie i teraz będziemy chcieli również wygenerować
sobie odpowiedzi, w taki sposób jak tutaj widzisz.
A ja chciałbym żeby każda z nich była niezależnym komponentem, bo to po prostu dużo sprawę ułatwi.
Za moment kiedy będziemy chcieli wiedzieć czy np. dany element jest zaznaczony itd.
Dlatego chciałbym coś takiego jak tutaj mamy też sobie wyciąć, a w to miejsce zrobimy sobie komponent
answer, zaraz zrobimy to w pętli, ale musimy go najpierw zaimportować.
Zauważ, że importuje zanim go w ogóle otworzyłem.
Ale to nie ma problemu z tym, to będzie
błąd chwilowo w terminalu i to wszystko, tutaj jeszcze dodamy do components,
ok i teraz utworze taki nowy plik w katalogu 40 src components i Answer,
ok, nazwiemy go Answer, wkleimy jego templatkę tutaj, zaraz ją będziemy uzupełniać i on będzie tutaj przyjmował
również kilka prop.
Pierwszym z nich będzie answer, czyli jakby sama ta odpowiedź. Jeżeli byśmy tutaj weszli, mamy coś takiego
jak answers i taki obiekt a 6, to dla nas będzie jeden obiekt, który tutaj będzie za chwilę przekazany.
Natomiast chciałem również przekazywać question bo to nam się przyda po to że na question mamy coś takiego
jak id.
Więc stąd będziemy również mogli z tego skorzystać.
Czyli taki prop będzie przyjmował właśnie ten nasz komponent ale jeszcze być może jakieś style powinniśmy stąd
wyciągnąć, tak dla tego przycisku, żeby to wszystko wyglądało dobrze, bo one mają tutaj atrybut scoped, więc nie
działały by dla naszego answer. Wrzucam je w to miejsce, bo mamy tutaj klasy button i to powinno już nam
zacząć działać, więc teraz będziemy chcieli sobie wygenerować tutaj dynamicznie na podstawie answer
tę odpowiedź, ale wrócimy do question i zrobimy tak jak wspomniałem v-for, czyli będę chciał zrobić v-for
oraz będziemy chcieli iterować po question kropka answer, czyli napiszemy answer in question.answers, OK.
Będziemy chcieli zbindować tak jak mówiłem answer, przekazać to jako prop po prostu przed momentem powiedzieliśmy
że je przyjmiemy i następnie question również będziemy chcieli tam przyjąć.
Wystarczyłoby nam samo id question
id, tam moglibyśmy zrobić sobie tylko id ale tak też może być. Potrzebujemy jeszcze tutaj żeby Vue
nie narzekał, jakiś unikalny klucz żeby mógł identyfikować te elementy później w drzewie dom więc możemy
się odwołać do question.id.
Bo wiemy że każde pytanie ma tutaj inne id i dzięki temu będzie to unikalne, ok, tutaj to jeszcze troszeczkę
zmodyfikujemy.
Dlatego, że później będziemy potrzebowali wewnątrz takiej odpowiedzi answer mieć dostęp na przykład
do tego czy to jest a, b czy c.
Wyobraź sobie, że tak jak tutaj widzimy, mamy a, b czy c i zaznaczymy c, to chcielibyśmy wiedzieć, że to jest
c.
Dlatego tutaj zrobimy troszeczkę inaczej przy tej pętli i tutaj gdzie iterujemy po tym obiekcie question
answers, w zasadzie to nie jest tablica zauważ tylko jest to obiekt to musimy interować troszeczkę
w inny sposób.
Możemy sobie tutaj w Vue powiedzieć że chcemy mieć answer.
I to będzie wartość np. 6, a klucz to jest key.
I tutaj napiszemy sobie answer i key i dzięki temu jako nasze answer nie będziemy przekazywać samej tej
odpowiedzi tylko przekażemy sobie taki obiekt który będzie miał wewnątrz
answer i to będzie answer ale w ES6 nie musimy tego dwa razy przekazywaćm wystarczy że zrobimy tutaj że
key ma to być key i answer, czyli mam nadzieję, że rozumiesz. Ten obiekt wpadnie nam tutaj pod this answer
i w nim będziemy mieć kropka key to będzie np. a, b czy c, a kropka answer to będzie odpowiedź, więc teraz to tutaj
powinno mieć sens.
Zróbmy sobie coś takiego czyli answer.key, postawimy kropkę i następnie answer.answer, ok,
zobaczmy czy to w ogóle ma sens.
Okazuje się, że tak, jak najbardziej, jest w porządku i to nam się później jeszcze przyda.
Jak zatem widzisz, nasz widok się już generuje, bo zrobiliśmy sobie tutaj taką odpowiedź. Mamy pytanie,
mamy quiz, czyli w zasadzie tutaj wszystko działa już w bardzo fajny sposób i sprawdzimy tylko jedną
rzecz czy to będzie dynamiczne jeżeli zmienimy tutaj currentQuestion.
Nie możemy tego zmienić bezpośrednio w store, ale jeżeli przejdziemy do components, zaznaczony np. aplikację
i mamy tutaj wiem vm0 to mogę wpisać vm0.
I chociaż momencik, mamy tutaj jakiś błąd, zobaczmy, duplicate key.
To znaczy, że w miejscu gdzie robiliśmy question gdzieś nie podaliśmy unikalnego klucza, ok i rzeczywiście
ja tak jak się teraz zastanowię, to popełniłem błąd, bo question.id
będzie mało to id np. dla trzech odpowiedzi.
Przecież tutaj takie samo.
Więc pod key może najlepiej dajmy key czyli to będzie a, b lub c i wtedy nie będzie zduplikowane, ale dobrze że Vue nam o
tym wspomniał,
mogliśmy to naprawić.
Ok, ale raz jeszcze spróbujmy się odwołać tutaj do vm0, następnie do store z dolarem i następnie odwołamy
się do state i będziemy chcieli zmienić currentQuestion np. na dwa. Zobaczmy, jak widzisz po zmianie
jest to odzwierciedlane na stronie, więc jest wszystko w porządku. Natomiast później jak przejdziemy
na VueRouter, to będziemy też z tego korzystać, ale w troszeczkę inny sposób, VueRouter będzie decydował, które
pytanie ma się wyświetlić.
Niemniej jednak jeśli chodzi o samo wyświetlanie tych komponentów, to już nam się to udało i z tego json'a
które pobieramy z serwera wyświetlamy sobie wszystkie pytania.
Więc jak widzisz tę lekcję możemy już uznać za skończoną, a w kolejnej zajmiemy się pisaniem logiki, tak
aby można było zaznaczać te odpowiedzi i tak dalej.