API a ajax ve Vue.js

Vue je pro zpracování ajaxových aplikací jak dělané. Poskytuje jednoduchou aplikační vrstvu, jak vykreslovat získaná data do šablony a reaktivně reaguje na stažení nových záznamů.

Upozornění:

Všechny ukázky používají proměnnou basePath, která obsahuje základní cestu k API endpointu. Proměnnou si definujte sami a může obsahovat napříkad doménu, kde je API hostováno.

Pokud používáte Nette framework, může definice v layoutu vypadat například:

<script>let basePath = {$basePath };</script>.

Lazy loading - získání dat při zobrazení šablony/komponenty

Vue nativně podporuje lazy loading, který zajistí dynamické získání dat až v okamžiku, kdy jsou skutečně potřeba.

Jeden z doporučovaných způsobů, jak přistupovat k vývoji webu je načítat data do komponent až v případě, kdy jsou poprvé zobrazena - tedy v okamžiku, kdy se komponenta poprvé vykresluje do stránky.

Připravme si proto komponentu, která načte svoje data až při prvním výskytu ve stránce:

Vue.component('exchange-rates', {
    template: `<div class="exchange-rates">{{ content }}</div>`,
    data: function () {
        return {
            content: 'Načítám...'
        }
    },
    created() {
        fetch(basePath + '/api/v1/exchange-rates')
            .then(response => response.json())
            .then(json => {
                this.content = json.content;
            });
    }
});

Jádro celé komponenty tvoří šablona, prázdné datové uložiště s výchozím textem a metoda created(), která se zavolá při první inicializaci komponenty.

Inicializace komponenty je okamžik, kdy se komponenta poprvé vloží do stránky nebo jiné komponenty. Pokud komponentu vkládáme opakovaně, bude se každá instance inicializovat znovu.

Zavolání API endpointu

Vue předpokládá, že na serveru běží API, s kterým je možné napřímo komunikovat. Výhodné je data přenášet ve formátu json, který Vue umí nativně zpracovat a případně pomocí cyklů vykreslit i složitější data, jako jsou například seznamy, tabulky a podobně.

Samotné zavolání API se dělá funkcí fetch() následovanou zpracováním dat.

Například:

fetch(basePath + '/api/v1/exchange-rates')
    .then(response => response.json())
    .then(json => {
        // zpracování dat
    });

Veškerá získaná data jsou k dispozici v proměnné json a můžeme s nimi udělat cokoli, například je zapsat do datové části komponenty.

Zobrazení stavu načítání (spinner)

Pro zachování dobrého uživatelského zážitku a signalizaci, že se něco děje, je dobré do stránky vložit symbol načítání.

Například spinner:

Jen příklad, nic se nenačítá.

Spinner je možné vložit velmi jednoduše například přes komponentu z Bootstrapu:

<b-spinner label="Loading..."></b-spinner>

Komponentu můžete získat v oficiální dokumentaci Bootstrapu pro Vue.

Animace pro loading se poté v rámci komponenty řeší obvykle tak, že se zobrazuje na základě podmínky o prázdnosti dat. Pokud jsou data prázdná (začátek životního cyklu komponenty), zobraujeme animaci načítání. Až se komponenta naplní daty ajaxem, bude mít datová proměnná svůj vlastní obsah, proto podmínka přestane platit a místo animace načítání se zobrazí samotná data.

Kompletní složitější příklad:

Vue.component('cms-dashboard', {
    template:
    `<div v-if="content === null">
        <b-spinner label="Loading..."></b-spinner>
    </div>
    <div v-else>
        {{ content }}
    </div>`,
    data: function () {
        return {
            content: null
        }
    },
    created() {
        fetch(basePath + '/api/v1/cms/dashboard')
            .then(response => response.json())
            .then(json => {
                this.content = json.items;
            });
    }
});

Tuto komponentu v upravené verzi používám na hlavní stránce administrace. Úkolem je stránku do prohlížeče dostat co nejdřív, aby mohl uživatel kliknout do menu a pokračovat na další stránky. Pokud i přesto chce vidět připravený obsah hlavní strany, načte se za několik stovek milisekund ajaxem, díky čemuž se celý proces načítání stránky nesrovnatelně zrychlí.

Zpracování dat na serveru

Pokud pro zpracování dat používáte jazyk PHP, je potřeba znát úskalí, která to přináší. Více podrobností jsem rozepsal v článku Zpracování ajaxových POST požadavků v PHP.