Prosty i Nowoczesny Framework dla Vue.js
7 godz. 2 min · Vue.js · Full-stack i Programowanie
Wojciech PołowniakSr. Fullstack EngineerW tym projekcie tworzyć będziemy praktyczny projekt - klona Wikipedii! Minipedia pobierze dane z prawdziwego źrodła danych, zewnętrznego API WikiMedia - będzie łudząco podobna do oryginału oraz współdzieliła najważniejsze funkcjonalności, takie jak dostarczanie treści w różnych wersjach językowych, możliwość wyszukiwania artykułów, czy pobieranie najpopularniejszych wpisów dla danego języka. Stworzymy także podstronę wyświetlającą za każdym razem losowy artykuł w danej wersji językowej.Zobaczysz też, jak dokonać migracji ze statycznej strony HTML na Nuxt - oraz jak tworzyć przykładowe komponenty podczas tego procesu.Dzięki temu wszystkiemu, dowiesz się jak wykorzystać nabytą wiedzę w praktyce.
Dzięki Nuxtowi dowiesz się jak optymalizować Twoje strony www z duchem idei progressive enhancement, dostarczając coraz to lepsze doświadczenia dla swoich użytkowników oraz tworząc aplikację napisaną w 100% w JavaScript, która będzie działała nawet wtedy, gdy użytkownik jawnie wyłączy go w przeglądarce! To wszystko za SSR (Server Side Rendering), dzięki któremu treści będą gotowe do konsumpcji już przy wstępnej, pierwszej odpowiedzi z serwera WWW.Oczywiście, ma to swoje implikacje na wydajność naszej aplikacji - sprawiając że Lighthouse czy optymalizacja pod SEO staje się coraz prostsza!
Czymże jest ekosystem danego frameworka bez wsparcia społeczności! Dlatego podczas tego kursu nauczysz się instalować i wykorzystywać różne pluginy i moduły, które zaoszczędzą Ci dużo czasu. Dowiesz się też, jak tworzyć własne moduły - które rozszerzą działanie Twojej aplikacji Nuxt w sposób czysty i zarządzalny.
Nuxt jest frameworkiem w którym pracujemy zarówno po stronie front-endu, jak i back-endu. W związku z czym, stworzymy swoje własne API (bazujące na express.js) które będzie pewnego rodzaju pośrednikiem pomiędzy API WikiMedia oraz Twoją aplikacją internetową.
W tym kursie, dowiesz się także jak tworzyć swoje własne Middleware'y - czyli fragmenty kodu wywoływane pomiędzy przechodzeniem między stronami, czy podczas innych zapytań HTTP.Dodatkowo, zobaczysz jakie narzędzia daje nam Nuxt aby tworzyć progresywne aplikacje internetowe, oferując wsparcie dla takich funkcjonalności jak np. animacje między przejściami pojedynczymi podstronami naszego serwisu.
Tajemnicze i18n - czyli numeronim odpowiadający angielskiemu słowu "internalisation" - odnosi się w kontekście web developmentu do tłumaczenia danych na różne języki. Podczas realizacji projektu Minipedii, nie tylko wykorzystamy standardowe podejście do tłumaczeń stałych elementów naszego interfejsu użytkownika, ale także przetłumaczymy same dane zwracane z API, wykorzystując inną wersję językową w zależności od preferencji użytkownika!
Poznasz też kilka ciekawych pluginów i rozwiązań dotyczących optymalizacji pod SEO - poza faktem, że podejście spełniające intencje użytkownika jest najlepszym, co możemy zrobić - pluginy generujące nam mapę stron automatycznie na podstawie zadeklarowanych przez nas podstron, czy generatory danych jsonld pomogą w pozycjonowaniu Twojej wydajnej aplikacji jeszcze wyżej w hierarchii wyszukiwarek.
Aby móc efektywnie korzystać z tego kursu, powinieneś posiadać średnio zaawansowaną wiedzę z kategorii Front End, z naciskiem na umiejętność posługiwania się JavaScriptem oraz solidne podstawy NodeJS. Konieczna jest znajomość Vue, jako że Nuxt jest frameworkiem korzystającym z niego u swoich podstaw. Jeśli czujesz się dość swobodnie w wyżej wymienionych aspektach web developmentu, ten kurs będzie idealny dla Ciebie.
Cześć!
Z tej lekcji skupimy się tylko i wyłącznie na komponencie.
Full info box, czyli postaramy się, aby ładował się tutaj prawdziwy MIME image
obrazka i zajmiemy się tutaj tymi nazwami pojedynczych właściwości,
które w tym momencie wyświetlają się jeden do jednego.
I chyba nad tym się na początku skończymy tą sekcją wybudowaną.
Czyli jeśli sobie stworzymy tutaj nowy terminal.
Przejdziemy tutaj do kolejnej lekcji, do lekcji 20.
I odpalimy npm install dodasz.
No to będziemy w stanie korzystać z całych
dobrodziejstw Logitecha i jedną z takich funkcji, która nas będzie
interesowała tutaj jest funkcja status start case.
Tutaj chyba nie widać, bo to nie jest dokumentacja.
Jeszcze tutaj mamy informację jak ją
zainstalować i tu jest przycisk do dokumentacji
i możemy tutaj sobie wpisać start start case i ta funkcja konwertuje nam dowolny
string na taki tekst, który wygląda mniej więcej jak.
To, jak piszemy normalne zdania, w związku z czym wykorzystamy sobie te funkcje.
Będziemy musieli oczywiście zaimportować Judasza.
Czyli tutaj w naszym komponencie.
Import from pilotaż.
Prawdopodobnie będziemy musieli tutaj zrobić gwiazdka na slajdach.
Zobaczymy. Wydaje mi się, że tak powinniśmy zrobić.
Możliwe, że nie.
I tutaj deklarujemy nową metodę news.
Convert to.
Start ok.
I ta metoda będzie właśnie korzystała z tego, co sobie tutaj kupowaliśmy.
I wykorzystamy tutaj właśnie tę metodę,
którą znaleźliśmy, czyli będziemy zwracali wynik funkcji start case.
I tutaj to, co przekażemy sobie w parametrze, czyli powiedzmy string.
I musimy oczywiście zrobić to nie jest
indeks, kropka, więc to sobie przeniesiemy tylko w naszym komponencie.
Halifax.
Full info box otwieramy.
Tutaj ten komponent
ewidentnie jest cięższym komponentem niż cała reszta
i wynika to ciekawe tylko i wyłącznie z tego jak API jest zbudowane.
W związku z czym to też jest częsta
sytuacja, że jeśli stworzymy nasze API w słaby sposób,
tudzież po prostu niedostosowane do tego co będziemy robić w projekcie,
to czasami się tak zdarza, że po prostu musimy robić różne hacki na front endzie.
No i jako że my tutaj operujemy z zewnętrznym API, nie
bardzo jesteśmy w stanie tutaj zmodyfikować tego API, więc musimy robić
takie tudzież różnego rodzaju adaptery do API,
które będą tak jakby pośredniczył między tym z czym pracujemy bezpośrednio.
Następca przychodzi nam z API.
W każdym razie, jeżeli wykorzystamy metodę Convert to Start case
i przetestujemy ją po prostu robiąc jakiś przykładowy Heloł Kamil Hack.
Zapiszemy i zobaczymy czy da się w ogóle.
Renderuje i jest błąd failed.
Chyba nie było tam przecinka gdzieś na dole.
Tak, oczywiście tutaj nie ma przecinka.
Zapiszmy.
I to się nam powinno wyświetlić tutaj na samym dole w tym komponencie.
Hello, Kamerka jest tutaj się wyświetliła,
w związku z czym faktycznie widzimy, że to działa.
I jedyne co musimy teraz zrobić, to po prostu wykorzystać tą metodę,
pozbyć się jej z naszego widoku i wykorzystać ją tutaj w pierwszym
parametrze czy w pierwszej komórce naszej tabeli naszego wiersza.
No i jak zapiszemy to, to w tym momencie
teoretycznie te najciekawsze i wszystkie inne właściwości powinny się
zaadaptować do takich wielkości jakich byśmy się ich spodziewali.
Tutaj chyba jest jakiś problem z CSS em.
Moglibyśmy dać jakąś stałą szerokość tej
tabeli, aby one zawsze były przynajmniej jakieś.
Natomiast jest to detal wizualny.
Nie będziemy się tym chyba przejmować.
Najważniejszy jest ten obrazek w tym
momencie i z tym obrazkiem niestety troszkę będziemy musieli się namęczyć.
W związku z czym przejdźmy od razu do roboty.
Fika możemy pominąć, ponieważ ciężko jest tutaj określić jaka to będzie fika.
Niestety API nie zwraca nam takich informacji.
Tutaj oczywiście, ale przynajmniej dekoracyjnego dajemy.
Nie jest to do końca obrazek dekoracyjny,
ale ciężko też powiedzieć jak to będzie przedstawione.
MIME image for the query.
Możemy sobie napisać np.
a caption.
Tak samo możemy Name image of.
Main thing.
I tutaj możemy wstawić faktycznie co to jest?
Jesteśmy w stanie to zrobić jak podzielimy
nasze widoki na osobne podstrony i będziemy mieli dostęp do
informacji jaką podstronę obecnie oglądamy.
W tym momencie nie jesteśmy tego w stanie
zrobić, ale sam obrazek wyświetlić jesteśmy w stanie.
W związku z czym mail on już tutaj nam się pokazuje.
Tutaj nam się alt nawet uruchomił.
Zobaczmy jak wygląda treść naszego mailingu.
I jak widzimy jest.
Jest to ścieżka do obrazka.
Została wykryta przez to, że mamy tutaj kropka png na końcu,
ale jest to ścieżka relatywna do naszego projektu i tak naprawdę nie jesteśmy w
stanie stwierdzić, gdzie konkretnie w internecie leży ten
obrazek i dlatego wykorzystamy tutaj nasze image.
Które zwraca po prostu wszystko.
Każdy jeden obrazek, który znajduje się na danej stronie.
Czyli zrobimy sobie konsolę lub.
Pastor.
Stats real images.
I tutaj też to akurat nam się ładnie wypisze w
konsoli, więc nie musimy tego stringi wstawiać.
Odświeżam, bo wymaga odświeżenia strony.
Niestety link nie uruchamia.
I tutaj nie widzę.
Co prawda.
Tego co sobie wpisaliśmy.
Możliwe, że tak.
To jest news, a nie ma.
Zobaczmy czy nie mamy drugiego z paskiem.
Nie mamy, więc zapiszemy i ponownie odświeżamy.
Oho!
Wyczyścił stronę ponownie.
Zatrzymajmy i zobaczmy, co tam się znajduje.
Robimy więc. To są informacje, które dostajemy.
Z naszego API i mamy na każdym z tych elementów tablicę
pole Image info i to info zawiera w sobie bazę.
Dużo informacji, mamy description,
description, short url i tutaj są różne informacje o tym obrazku.
Nas bardziej interesuje faktyczna jego nazwa.
I tutaj widzimy, że w title zawiera się ta
informacja, a więc możemy przejść kierować się przez wszystkie
robimy i poszukać tego obrazka, który był zadeklarowany jako kolejny mecz.
Tutaj też będziemy musieli zrobić jako include.
Nie jest to idealne rozwiązanie,
ale pracujemy z tym co mamy, w związku z czym tak na tablicy robimy.
Szukamy na każdym z obiektów pola title i szukamy w nim naszego Main image.
I zróbmy to tutaj.
Find.
Image.
Image. Kropka.
Title.
I klucz.
I tutaj nasz image.
I zwrócimy ten element, jeśli uda się go
znaleźć, bo możliwe, że się nam nie uda ze względu na jakiś błąd programistyczny.
Jakiś błąd się pojawił.
Ciekawe.
Fajnie byłoby mieć na koncie mecze jest fajne.
Oczywiście musimy tutaj zarobić pieniędzy.
Bo jest to nasz kompas.
Zdefiniowane tutaj.
Poczekamy.
I faktycznie znalazł jeden obiekt.
I na tym obiekcie powinniśmy mieć już
informację o tym, jaki jest jego bezpośredni obraz.
Tutaj mamy nawet jego dyskretny URL.
Jestem ciekaw, czy bylibyśmy w stanie
jakoś pobrać deskryptory tego obrazka programowo.
Zobaczmy co tam się dzieje.
Do czego to nas przekieruje?
Nie ma tutaj.
Informacji.
Są to opisy, ale wydaje mi się, że nie ma
sensu pobierać tych informacji i wyświetlać osobno.
Możemy to po prostu pominąć, więc poszukajmy po prostu.
Gdzie w naszym API znajduje się
absolutny link do tego pola, bo powinien się tam znaleźć.
Jeśli dobrze pamiętam API wiki to jest wiki czy jest dalej?
Warto zawsze pamiętać, że jeżeli pracujemy
z API to trzeba spoglądać do tego jak jest ono zbudowane i.
Co jest napisane w jego dokumentacji.
Czy jest tutaj jakaś dodatkowa informacja?
Czego się tam możemy spodziewać?
Robimy jazz?
Niestety nie bardzo.
Ciekaw jestem.
Wewnątrz nie powinna być, a tu jest oczywiście, ale mi się schował.
W związku z czym skoro mamy już obiekt, zrobimy, że jesteśmy w stanie pobrać z
niego info URL i w taki sposób wyświetlić ten obraz, więc to też zróbmy.
Przenieśmy sobie tę logikę.
Do osobnego kompozyt property.
I być może zmienimy tutaj tą logikę, która będzie nam zwracała
pierwszy obrazek, bo nie jest to już nam w tym momencie potrzebne, chociaż
prawdopodobnie dobrze byłoby w pewnym sensie zostawić tego support.
Ale wydaje mi się, że mamy też tutaj za komentowane w naszym sektorze konsolowym.
Bez star state MIME image.
Więc będziemy mieli do tego dostęp potencjalnie.
Ja tutaj to skomentuję tylko chwilowo.
Tego fragmentu kodu się tam pozostawmy,
niech się renderuje to co ma się tam wyrenderować.
Strona się już chyba przebudowana, ale ją odświeżamy.
Pomyślmy troszkę.
Pasek narzędzi przeglądarki.
I faktycznie wypisał nam się tutaj.
Czy to jest faktycznie main image?
Wydaje mi się, że nie był to bezpośredni
link do obrazków, przynajmniej nie w każdym tagu, które oglądałem.
Ale załóżmy, że faktycznie to wystarczy i nie potrzebowaliśmy w ogóle pracować nad
tamtym podejściem, które będzie nam szukało.
Zrobimy z naszego obrazka.
I faktycznie chyba to się w tym przypadku akurat sprawdziło.
Jestem ciekawy czy jak zmienimy to na coś innego czyli np.
routing, metro, wieże.
Zmienimy to na.
Robimy. Czy moglibyśmy?
Batmana.
I zobaczymy czy faktycznie podmieni się na obrazek Batmana.
Po odświeżeniu strony oczywiście.
I faktycznie zadziałało.
W związku z czym być może.
W innym fragmencie tego API będziemy musieli zrobić tego typu trick, czyli po
prostu wyszukać obrazek na podstawie jego nazwy, a potem znaleźć go w rogu.
Jeżeli nie mamy takiej potrzeby, to tym lepiej dla nas.
Mniej kodu, ale tak jak widzimy mamy tutaj już cały nasz full info box,
który być może nie wygląda najlepiej ze względu na.
Jego szerokość.
Jestem ciekaw czy możemy tutaj po prostu ustawić minimalną szerokość
na jakąś wartość powiedzmy 300 pikseli i to się nam troszkę rozszerzy.
Natomiast ta treść będzie miała priorytet, więc moglibyśmy ustawić to na kolumnie,
ale tak jak mówiłem nie ma to większego znaczenia, a na różnych podstronach te.
Ten box może mieć też różną szerokość.
W związku z czym zostawmy to na tym etapie.
I tym sposobem faktycznie pobieramy nasze
informacje z API, wyświetlamy je na naszym front endzie i
jak byśmy sprawdzili to faktycznie one są renderowane na backend.
Bo gdy otworzymy źródło strony to te informacje są tam od razu zawarte.
W następnych lekcjach oczywiście jeszcze będziemy czyścić komponenty.
Indeks.
Tak, aby nie znajdowały się tutaj w ogóle żadne zakamuflowane HTML.
W miarę możliwości niektóre rzeczy będą związane z
działaniem, a nie z całą treścią, którą zaciągamy z API.
Ale tutaj widzę, że sama moglibyśmy zrobić.
Tak naprawdę nawet nie jest to koniecznie.
Coś, co musielibyśmy wrzucać w komponent, więc moglibyśmy tutaj po prostu wrzucić.
Star Stable Summary i prawdopodobnie też by zadziałało.
Usuńmy, odświeżamy i faktycznie to działa.
W związku z czym większość tej treści mamy już tutaj zrobioną.
I tak samo References.
Moglibyśmy tutaj zrobić, ale nie znajdzie się już na to czas w następnych lekcjach.
Zmiany wprowadzone w lekcji · 13 min
diff --git a/20/minipedia/components/FullInfoBox.vue b/20/minipedia/components/FullInfoBox.vue
index 76b7e08..725fd11 100644
--- a/20/minipedia/components/FullInfoBox.vue
+++ b/20/minipedia/components/FullInfoBox.vue
@@ -5,9 +5,9 @@
<td colspan="2">
<figure>
<img
- :src="mainImage">
+ :src="mainImage" alt="Main image for the query">
<figcaption>
- To be filled
+ Main image representing
</figcaption>
</figure>
</td>
@@ -15,13 +15,14 @@
<tr v-for="detail in textDetails">
- <td>{{ detail[0] }} </td>
+ <td>{{ convertToStartCase(detail[0]) }} </td>
<td>{{ renderOption(detail[1]) }} </td>
</tr>
</table>
</div>
</template>
<script>
+ import * as _ from 'lodash'
export default {
props: {
content: {
@@ -43,19 +44,13 @@
});
},
mainImage() {
- const firstImageBasedOnValue = this.details.filter(detail => {
- const detailValue = detail[1];
-
- if (typeof detailValue !== 'string') {
- return false;
- }
- return detailValue.includes('.PNG')
- })[0];
-
- return firstImageBasedOnValue[1];
+ return this.$store.state.mainImage;
}
},
methods: {
+ convertToStartCase(string) {
+ return _.startCase(string);
+ },
renderOption(option) {
if (Array.isArray(option)) {
return option.join(', ');
diff --git a/20/minipedia/package.json b/20/minipedia/package.json
index 7f7decc..f6f7a2a 100644
--- a/20/minipedia/package.json
+++ b/20/minipedia/package.json
@@ -14,6 +14,7 @@
"@nuxtjs/axios": "^5.13.1",
"core-js": "^3.9.1",
"envalid": "^7.1.0",
+ "lodash": "^4.17.21",
"nuxt": "^2.15.3",
"nuxt-basic-auth-module": "^1.4.0",
"v-tooltip": "^2.1.3"
diff --git a/20/minipedia/pages/index.vue b/20/minipedia/pages/index.vue
index 8054a79..3e4feaa 100644
--- a/20/minipedia/pages/index.vue
+++ b/20/minipedia/pages/index.vue
@@ -8,12 +8,7 @@
<FullInfoBox :content="$store.state.fullInfo.general" />
- <p>Janusz Korczak, the pen name of Henryk Goldszmit (22 July 1878 or 1879 – 7 August 1942), was a
- Polish Jewish educator, children's author and pedagogue known as Pan Doktor ("Mr. Doctor") or Stary
- Doktor ("Old Doctor"). After spending many years working as a principal of an orphanage in Warsaw, he
- refused sanctuary repeatedly and stayed with his orphans when the entire population of the institution
- was sent from the Ghetto to the Treblinka extermination camp by the Nazis, during the Grossaktion
- Warschau of 1942.</p>
+ <p>{{ $store.state.summary }} </p>
<TableOfContents :content="$store.state.content" />