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 podamy sobie obsługę routingu.
Chociaż być może zauważyłeś że już router się pojawił.
Nie chciałem żebyśmy wszystko robili od zera, tak jak robiliśmy to już wcześniej. Pokazywałem jak to skonfigurować
więc teraz już ten router troszeczkę prekonfigurowałem tzn.
Otworzyłem katalog tutaj router, a w nim ten cały boilerplate, który jest nam potrzebny, a więc Vue
use VueRouter i tutaj eksportuje new VueRouter a routes będziemy sobie za moment uzupełniać.
Jeżeli nie pamiętasz jak to działało koniecznie wróć do lekcji o VueRouter gdzie o tym mówię, mamy na ten
temat cały rozdział w tym kursie.
I teraz jeżeli coś takiego zrobimy no to już ten router zaczyna nam działać.
Natomiast co my będziemy chcieli zrobić i jakie będziemy chcieli mieć ścieżki.
Może tym zajmiemy się najpierw, będę chciał mieć taką ścieżkę czyli path, jak ukośnik question, ukośnik
i tutaj będzie number, czyli numer tego oto pytania i chciałbym wtedy wczytywać component.
Oczywiście pewnie pamiętasz że tutaj musimy sobie te komponenty importować więc import Question from
to będzie jeden katalog do góry components, OK.
I będę chciał również nadać nazwę tej ścieżce.
Czyli jeżeli przypiszę jej name question, to będziemy mogli po name się do niej odwoływać.
I jeszcze jedna rzecz też ci o tym mówiłem.
Jeżeli wstawimy sobie props na wartość true, to wtedy number będzie do tego komponentu wstawiany jako
prop czyli nie będziemy musieli w tym komponencie nic wiedzieć o routerze jedynie będziemy mieli prop
o nazwie number więc żeby nie zapomnieć przejdźmy od razu do komponentu i tutaj gdzie on przyjmował
propy to przyjmijmy coś takiego jak number i pod this number będziemy mieli dostęp właśnie do tego miejsca.
Natomiast jeszcze jedną rzecz ja chciałbym zrobić.
Mianowicie chciałbym utworzyć przekierowanie, jeżeli ktoś przejdzie bezpośrednio na główny adres naszej
strony czyli path.
To będzie taki path, to chciałbym zrobić redirect do nazwanej ścieżki którą nazwaliśmy question a więc do tej
która jest pod spodem i w zasadzie możemy to tak zrobić i powiedzieć params
I tutaj number 1 lub mógłbyś tutaj zrobić po prostu path question ukośnik 1.
Też byłoby w porządku jak wolisz tak możesz zrobić, tutaj number zostanie podstawiony w to miejsce i powinno
to dobrze współpracować.
Jak widzisz tak też się dzieje, przenosimy się do
question 1.
Jeżeli zmienimy na dwa, niestety nic to nie daje ale tym właśnie teraz będę chciał się zająć.
Do tej pory nasz komponent Question wyświetlał aktualne pytanie, gdybyśmy tutaj zerknęli.
W zasadzie to będzie w quizie. Na podstawie question a question było tutaj czyli currentQuestion
minus 1.
Teraz ja chciałbym żeby ten number, który tutaj podaliśmy żeby to właśnie on był tutaj brany pod uwagę.
Swoją drogą zauważyłem, że źle troszeczkę postawiliśmy. Momencik, tutaj nie powinno być question, ale
Quiz,
więc zmieńmy to, pospieszyłem się troszeczkę,
OK.
Czyli chcemy ładować Quiz i to właśnie ten Quiz będzie otrzymywał prop,
o którym wspomniałem, czyli w zasadzie tutaj możemy go usunąć. Przepraszam cię za to małe zamieszanie,
wrócimy do Quiz i tutaj jest number. Odświeżmy,
czy to w jakiś sposób ma sens.
Zgadza się i teraz będę chciał zrobić rzecz taką, że podstawimy to w tym miejscu.
Ale przeszło mi przez myśl, taka myśl dlaczego to działa.
Pomimo tego że przed momentem zmieniałem, pewnie się domyśliłeś, że jeżeli nie to wyjaśnijmy to.
Nieważne co byśmy tam postawili.
I tak Quiz był wczytywany bo przecież w tym miejscu musiałem podstawić router-view.
Zapewne o tym pamiętałeś.
Ja z pośpiechu o tym zapomniałem.
Teraz jak widzisz ma to sens i jeżeli wrócimy do naszego Quiz'a tutaj i mamy to prop przekazane z paska adresu
pod this number, to będę chciał tutaj robić właśnie this number minus 1.
Natomiast żeby to była wartość nie string, ale numeryczna to przepuścimy ją sobie przez konstruktora number
bo z adresu jest zczytywane jako string i teraz to powinno mieć sens.
Zauważ że jeżeli pytania się będą zmieniać, to zmienia się to również w tym miejscu.
Jeżeli odpowiemy na pierwsze i jest ono tutaj dodawane, odpowiedzmy na trzecie, również id 3, jest tutaj
dopisywane czyli wygląda na to że zaczyna to działać już w porządku, no i również ten przycisk działa,
jeżeli wrócimy do pierwszego, chociaż w zasadzie tutaj wygląda na to, że nie, powinniśmy mieć możliwość
pójścia wstecz. Za moment się temu również przyjrzymy. Dlaczego jednak tak się dzieje, dlatego że tutaj
nie jest aktualizowany currentNumber, na którym currentQuestion, na którym bazujemy
również jeżeli zmieniamy nasz router, natomiast my będziemy ten router chcieli nie zmieniać tutaj ręcznie
ale za pomocą przycisków.
Więc może zajmijmy się teraz właśnie tymi akcjami.
Mam tutaj te przyciski i chciałbym do nich przypisać zdarzenia.
Chciałbym tutaj zrobić zdarzenie klik i następnie zrobić prevQuestion.
Taką metodę będziemy chcieli sobie wywoływać, a tutaj na klik, nextQuestion.
I teraz te metody będziemy musieli w quizie dodać, zaczniemy od prevQuestion.
I już ci tłumaczę co ja będę chciał zrobić.
Ja będę chciał zmienić currentQuestion, które mamy ale od niego zależy które pytanie jest wyświetlane,
tylko od tego co jest miejscu miejscu ale od currentQuestion zależą inne rzeczy.
Na nich wcześniej polegaliśmy, więc będziemy chcieli również to zmieniać i następnie będziemy chcieli programatycznie
z poziomu skryptu zmienić adres na pasku.
Więc tutaj musimy zrobić dwie rzeczy, pamiętasz że jeżeli chcemy modyfikować state to musimy to robić
za pomocą mutacji.
Czyli jeżeli tutaj mamy w naszym store
currentQuestion i chce to zmienić na inną wartość,
to zróbmy to z użyciem mutacji.
Przejdziemy tutaj i dodamy mutację o nazwie changeCurrent, która przyjmie state i przyjmie wartość, nazwijmy
ją tak samo jak wcześniej payload, a wewnątrz będzie to n, zaraz to zobaczysz i odwołamy się do state następnie
do current
Question, OK.
I będziemy chcieli zrobić
plus równa się payload.n czyli jeżeli przekażemy np. minus 1 to chce to zmniejszyć o jeden.
Jeżeli przekażemy jedynkę to będę chciał to dodać.
Czyli tak to będzie wyglądać i teraz z poziomu właśnie tego naszego Quiza, z tej metody będę chciał
zrobić this store commit, czyli taką mutację chce zacommitować, changeCurrent i będę chciał jej przekazać ten
payload w którym będę miał właśnie n i n to będzie wartość kolejnego pytania czyli będę chciał je po prostu
zmienić, w zasadzie nawet nie będzie to wartość tylko jeżeli prev to to będzie minus 1 a jeżeli będziemy robić
nextQuestion to to będzie plus 1.
Jeżeli to zmienimy tutaj to kolejna rzecz którą będę chciał zrobić to odwołać się do this router push
i będę chciał przejść do ścieżki nazwanej bo ją nazwaliśmy będzie to name question i params.
Może pamiętasz mieliśmy number, musimy stworzyć do tego obiekt,
number i tutaj będziemy mieli kolejną wartość czyli tak naprawdę będziemy się mogli odwołać do this
i następnie currentQuestion.
Bo skoro zrobiliśmy commit'a to currentQuestion się zmieniło i mamy tutaj taką computed property więc ona również zmieni
swoją wartość i wtedy będziemy mogli zrobić w ten sposób.
Mam nadzieję że to zadziała sprawdźmy.
Przejdziemy może całkowicie od strony głównej,
question 1.
Jeżeli kliknę, no właśnie wstecz, czyli musiałbym zacząć od powiedzmy drugiego pytania, ale to teraz nie
zadziała czyli przetestujemy to za sekundę kiedy zrobimy metodę next.
Ok więc zróbmy sobie metodę nextQuestion i tutaj będę chciał zrobić n 1 i w zasadzie trochę kodu zlikwidowaliśmy
więc może tutaj wystarczyło zrobić changeQuestion i podawać tutaj parametr, może to jest rzeczywiście lepszy
pomysł wtedy byśmy to zrobili w ten sposób ale OK na razie zostawmy to tak jak jest czyli tutaj będę
chciał robić taki commit, OK no w ogóle zobaczmy czy ma to sens.
Jak widzisz nic się nie dzieje mamy jakiś błąd.
Czyli wygląda na to że tutaj mamy nextQuestion a tutaj z jakiegoś powodu nie jest to widoczne.
Spróbujmy odświeżyć OK.
Czyli co się po prostu nie odświeżyło, widzimy że teraz to działa klikamy dalej i się nam to podmienia ale
przejdźmy może od strony głównej,
question 1.
Zmieniamy na
question 3.
Coś tutaj poszło o jeden krok za daleko ale zaraz to zdebuggujemy.
Teraz jest w porządku więc może ja po prostu kliknąłem dwukrotnie, tak zgadza się czyli jeżeli klikamy
raz to wszystko jest OK.
Teoretycznie jak dojdziemy do ostatniego pytania, ten przycisk powinien się wyłączyć, czyli nasza wcześniejsza
logika działa a możemy również wrócić kiedy wrócimy do pierwszego,
to się nam wyłącza czyli widzimy że ma to sens natomiast może szybko sobie to modyfikujmy na change
Question.
I tutaj będzie n które będziemy przekazywać i po prostu będziemy robić n czyli można to uprościć do
takiej postaci z użyciem ES6. Skoro i tak bardzo dużo kodu powtórzyliśmy, więc changeQuestion jeszcze zróbmy w tym miejscu.
No i tutaj będzie można przekazać ten parametr czyli tutaj podamy minus 1
a tutaj podamy 1.
Wydaje mi się że powinno to tak samo zadziałać.
Więc odświeżmy najlepiej, jak widzisz działa dokładnie tak samo, ostatnią rzeczą którą chciałbym w tej lekcji
dodać jest taka możliwość żebyśmy nie mogli przejść do kolejnego pytania jeżeli nie odpowiemy na aktualne.
Więc jak możemy to zrobić, chcę żeby ten przycisk był po prostu zablokowany, przejdziemy tutaj gdzie te
przyciski są czyli mamy to w tym miejscu i będę chciał doddać mu atrybut disabled,
jeżeli to pytanie nie jest odpowiedziane czyli jeżeli not answered, jeżeli not answered to nie możemy
przejść dalej więc computed property właśnie taką sobie tutaj dodamy answered i teraz jak sprawdzić czy
zadane pytanie już odpowiedzieliśmy czy nie.
Otóż będziemy musieli sprawdzić tutaj w tym Vuex storze w answers znajduje się identyfikator taki
jak id naszego pytania, ja zatem do tego celu będę chciał stworzyć sobie getter i tutaj getter będziemy
zwracać, czyli this store getters answered i będzie on dynamiczny, bo będę mógł mu przekazać this question
id.
Więc przejdźmy raz jeszcze do tych getterów i stwórzmy sobie taki getter answered on będzie podobny jak wyżej
bo też będzie zwracał funkcje skoro w ten sposób z niego korzystamy.
I tutaj w tej funkcji będziemy mieli question.id.
I tutaj sprawdzimy po prostu czy state następnie asnwers.
Wiemy, że jest to obiekt.
Czy on zawiera takie id, czyli question id.
I czy ono nie jest równe udefined no bo jeżeli tutaj nam zostanie zwrócony undefined znaczy że tam
nic nie ma.
Wydaje mi się że to powinno nam wystarczyć.
Spróbujmy raz jeszcze tutaj odświeżyć, jakiś błąd się pojawia więc szybko co tutaj jest nie tak.
Ok trudno powiedzieć.
Sprawdźmy jaki mamy tutaj opis tego błędu.
Ok,
duplicate jak widzisz czyli znowu disabled, być może to zauważyłeś.
Ja tego nie wyłapałem w tym kodzie czyli prawdopodobnie tutaj dwa razy dodałem atrybut disabled i on już tutaj
był.
Ja go dałem jeszcze raz, one się nie łączą więc musimy tutaj zrobić po prostu taki warunek jeżeli not answered lub
nie ma następnego wtedy ten przycisk ma być zablokowany.
Ok no i na pierwsze pytanie nie odpowiedzieliśmy więc nie powinniśmy móc przejść do następnego.
Tak też się dzieje.
Jeżeli odpowiem to już możemy przejść dalej.
Mogę wrócić i zmienić odpowiedź, tutaj jeśli odpowiem dopiero wtedy mogę przejść dalej.
Więc zaczyna to fajnie działać.
Teraz już nie mogę przejść dalej bo jesteśmy na ostatnim pytaniu.
No i tutaj właśnie będziemy chcieli wyświetlać przycisk zakończ a to zrobimy w lekcji kolejnej gdzie
wyświetlimy się jeszcze podsumowanie a więc w tej lekcji to tyle z mojej strony.