Tworzenie SPA z paginacją: Porównanie frameworków

Wstęp

W dzisiejszym cyfrowym świecie, aplikacje SPA zyskują popularność. Wynika to z ich płynności, wydajności i przyjaznego doświadczenia. SPA ładuje jedną stronę HTML i dynamicznie aktualizuje zawartość. Aby osiągnąć to dynamiczne zachowanie, SPA wykorzystuje różne technologie i biblioteki JavaScript.

Artykuł przedstawia trzy popularne metody tworzenia SPA, które różnią się stopniem zaawansowania i elastyczności. Zaczniemy od omówienia najprostszego podejścia, wykorzystującego bibliotekę jQuery. Przejdziemy do zaawansowanych rozwiązań, jak React.js i Vue.js. Oferują większą kontrolę nad strukturą i zachowaniem aplikacji. Ułatwiają zarządzanie stanem aplikacji.

  1. jQuery – Ta biblioteka JavaScript, choć nie jest dedykowana do tworzenia SPA, może być używana do prostych rozwiązań. Pozwala na łatwe manipulowanie elementami DOM, obsługę zdarzeń i wykonywanie żądań AJAX. W naszym przykładzie zobaczymy, jak wykorzystać jQuery do pobierania danych z serwera i wyświetlania ich w tabeli z paginacją.
  2. React.js – Jest to popularna biblioteka JavaScript stworzona przez Facebook, która znacznie ułatwia tworzenie interaktywnych interfejsów użytkownika. React opiera się na koncepcji komponentów, które można ponownie używać i łączyć, aby zbudować całą aplikację. W drugim podejściu omówimy, jak stworzyć tabelę z paginacją, używając komponentów React i zarządzania stanem.
  3. Vue.js – To kolejna popularna biblioteka JavaScript, podobna do React, ale z nieco lżejszym podejściem i prostszą strukturą. Vue.js używa systemu komponentów, oferuje dodatkowe narzędzia. Są to dyrektywy i transycje dla zaawansowanych interfejsów użytkownika. W trzecim podejściu zobaczymy, jak zaimplementować tabelę z paginacją, używając komponentów Vue.js i zarządzania stanem.

W przykładach użyjemy pobierania danych z end-pointa API, który można stworzyć korzystając z artykułu: Tworzenie endpointów API w Symfony z API Platform

Implementacja paginacji w SPA z wykorzystaniem jQuery

Zacznijmy od prostego podejścia z jQuery. Wykorzystamy bibliotekę jQuery do obsługi żądań AJAX, dzięki czemu będziemy mogli dynamicznie pobierać dane z serwera bez konieczności przeładowywania strony. Następnie, użyjemy funkcji manipulacji DOM dostarczanych przez jQuery, aby dynamicznie wypełnić tabelę danymi i dodać paginację. Mimo że jQuery nie jest dedykowanym rozwiązaniem do tworzenia SPA, może być wystarczające dla prostych projektów.

Poniżej znajduje się kod jQuery, który pokazuje, jak zaimplementować paginację w SPA:

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SPA z paginacją przy użyciu jQuery</title>
    <!-- Dołączenie Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
    <!-- Dołączenie jQuery -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
    <div class="container">
        <table id="people-table" class="table table-striped">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Imię</th>
                    <th>Nazwisko</th>
                    <th>Wiek</th>
                    <th>Email</th>
                </tr>
            </thead>
            <tbody>
                <!-- Wiersze z danymi zostaną wypełnione dynamicznie -->
            </tbody>
        </table>
        <div id="pagination" class="d-flex justify-content-center">
            <button id="previous-page" class="btn btn-primary mx-2">Poprzednia</button>
            <span id="current-page" class="align-self-center">1</span>
            <button id="next-page" class="btn btn-primary mx-2">Następna</button>
        </div>
    </div>
    <script>
        let currentPage = 1;

        function fetchAndRenderPeople() {
            $.getJSON(`http://ormsymfony.localhost/api/people.json?page=${currentPage}`, function (data) {
                const tableBody = $("#people-table tbody");
                tableBody.empty();

                data.forEach(function (person) {
                    const row = $("<tr></tr>");
                    row.append(`<td>${person.id}</td>`);
                    row.append(`<td>${person.name}</td>`);
                    row.append(`<td>${person.surname}</td>`);
                    row.append(`<td>${person.age}</td>`);
                    row.append(`<td>${person.email}</td>`);

                    tableBody.append(row);
                });
            });
        }

        fetchAndRenderPeople(); // Pobieranie danych na starcie aplikacji

        $("#previous-page").click(function () {
            if (currentPage > 1) {
                currentPage--;
                fetchAndRenderPeople();
            }
        });

        $("#next-page").click(function () {
            currentPage++;
            fetchAndRenderPeople();
        });
    </script>
</body>
</html>

W powyższym kodzie HTML stworzyliśmy prostą stronę, która zawiera tabelę z paginacją. Dołączyliśmy Bootstrap dla stylów oraz jQuery dla manipulacji DOM i obsługi żądań AJAX. Następnie zaimplementowaliśmy funkcję fetchAndRenderPeople, która pobiera dane z serwera i dynamicznie wypełnia tabelę danymi. Dodatkowo obsługujemy zdarzenia kliknięcia przycisków paginacji, aby można było przechodzić między stronami.

React.js – SPA oparte na komponentach z paginacją

Kolejnym rozwiązaniem jest React.js, który pozwala na tworzenie SPA opartych na komponentach. W przypadku React.js, tworzymy komponenty dla tabeli i paginacji. Wykorzystujemy hooki jak useState i useEffect, zarządzamy stanem i łączymy z serwerem. React.js jest idealny dla złożonych projektów.

Aby rozpocząć pracę z React.js, musimy najpierw zainstalować środowisko deweloperskie, Create React App, za pomocą polecenia:

npx create-react-app my-spa-pagination

Następnie przejdź do folderu z projektem:

cd my-spa-pagination

Teraz zainstalujmy Bootstrap, aby dodać style do naszej aplikacji:

npm install bootstrap@latest

W pliku src/index.js zaimportuj plik CSS Bootstrap:

import 'bootstrap/dist/css/bootstrap.min.css';

Teraz utwórz plik src/PeopleTable.js i wklej poniższy kod:

import React, { useState, useEffect } from 'react';

const PeopleTable = () => {
    const [people, setPeople] = useState([]);
    const [currentPage, setCurrentPage] = useState(1);

    useEffect(() => {
        fetch(`http://ormsymfony.localhost/api/people.json?page=${currentPage}`)
            .then((response) => response.json())
            .then((data) => setPeople(data));
    }, [currentPage]);

    const handlePageChange = (newPage) => {
        setCurrentPage(newPage);
    };

    return (
        <div>
            <table className="table table-striped">
                <thead>
                <tr>
                    <th>ID</th>
                    <th>Imię</th>
                    <th>Nazwisko</th>
                    <th>Wiek</th>
                    <th>Email</th>
                </tr>
                </thead>
                <tbody>
                {people.map((person) => (
                    <tr key={person.id}>
                        <td>{person.id}</td>
                        <td>{person.name}</td>
                        <td>{person.surname}</td>
                        <td>{person.age}</td>
                        <td>{person.email}</td>
                    </tr>
                ))}
                </tbody>
            </table>
            <div className="d-flex justify-content-center my-3">
                <button
                    className="btn btn-primary mx-2"
                    onClick={() => handlePageChange(currentPage - 1)}
                    disabled={currentPage === 1}
                >
                    Poprzednia
                </button>
                <span className="align-self-center">Strona {currentPage}</span>
                <button
                    className="btn btn-primary mx-2"
                    onClick={() => handlePageChange(currentPage + 1)}
                >
                    Następna
                </button>
            </div>
        </div>
    );
};

export default PeopleTable;

W powyższym kodzie stworzyliśmy komponent PeopleTable, który jest odpowiedzialny za wyświetlanie tabeli z danymi osób oraz paginację. W komponencie tym używamy hooków useStateiuseEffect do zarządzania stanem i pobierania danych z serwera.

  • useState jest używane do przechowywania stanu osób (people) oraz bieżącej strony (currentPage).
  • useEffect jest używany do pobierania danych z serwera za pomocą żądań fetch, gdy wartość currentPage ulega zmianie.

W funkcji handlePageChange zmieniamy wartość currentPage, co skutkuje ponownym pobraniem danych z serwera.

Sekcja JSX komponentu, wyświetlamy tabelę z danymi osób oraz przyciski paginacji. Przyciski paginacji zmieniają wartość currentPage, co powoduje aktualizację danych w tabeli.

W pliku src/App.js zaimportuj komponent PeopleTable i umieść go wewnątrz komponentu App:

import React from 'react';
import PeopleTable from './PeopleTable';

function App() {
  return (
    <div className="container">
      <h1 className="my-4 text-center">SPA Pagination with React.js</h1>
      <PeopleTable />
    </div>
  );
}

export default App;

Teraz nasza aplikacja wykorzystuje komponent PeopleTable, aby wyświetlić tabelę z danymi oraz paginację. Po uruchomieniu aplikacji w przeglądarce powinniśmy zobaczyć tabelę z danymi osób i przyciski paginacji, które pozwalają na przełączanie między stronami.

Uruchom aplikację, wpisując w konsoli:

npm start

Aplikacja powinna się otworzyć w przeglądarce na porcie 3000 (http://localhost:3000). W ten sposób zaimplementowaliśmy paginację w SPA przy użyciu React.js.

SPA Pagination z Vue.js

Na koniec, omówimy Vue.js, który również pozwala na tworzenie aplikacji opartych na komponentach. Podobnie jak w React.js, budujemy komponenty dla tabeli i paginacji w Vue.js. Używamy mechanizmów Vue.js do zarządzania stanem i łączenia z serwerem. Vue.js ma prostszą strukturę i dodatkowe narzędzia.

Zacznijmy od instalacji Vue.js, używając oficjalnego CLI (Vue CLI). Jeśli jeszcze go nie masz, zainstaluj go globalnie, wpisując w konsoli:

npm install -g @vue/cli

Następnie utwórz nowy projekt Vue.js, wpisując:

vue create my-vue-app

Przejdź do folderu z projektem i uruchom aplikację:

cd my-vue-app
npm run serve

Teraz dodajemy Bootstrap 5 do naszego projektu. Zainstaluj Bootstrap, wpisując:

npm install bootstrap@latest

W pliku src/main.js zaimportuj Bootstrap CSS:

import 'bootstrap/dist/css/bootstrap.min.css';

Utwórz nowy komponent PeopleTable.vue w folderze src/components. W pliku PeopleTable.vue umieść następujący kod:

<template>
  <div>
    <table class="table table-striped">
      <thead>
        <tr>
          <th>ID</th>
          <th>Imię</th>
          <th>Nazwisko</th>
          <th>Wiek</th>
          <th>Email</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="person in people" :key="person.id">
          <td>{{ person.id }}</td>
          <td>{{ person.name }}</td>
          <td>{{ person.surname }}</td>
          <td>{{ person.age }}</td>
          <td>{{ person.email }}</td>
        </tr>
      </tbody>
    </table>
    <div class="d-flex justify-content-center my-3">
      <button
        class="btn btn-primary mx-2"
        @click="handlePageChange(currentPage - 1)"
        :disabled="currentPage === 1"
      >
        Poprzednia
      </button>
      <span class="align-self-center">Strona {{ currentPage }}</span>
      <button
        class="btn btn-primary mx-2"
        @click="handlePageChange(currentPage + 1)"
      >
        Następna
      </button>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      people: [],
      currentPage: 1,
    };
  },
  methods: {
    handlePageChange(newPage) {
      this.currentPage = newPage;
    },
  },
  watch: {
    currentPage() {
      this.fetchData();
    },
  },
  created() {
    this.fetchData();
  },
  methods: {
    fetchData() {
      fetch(
        `http://ormsymfony.localhost/api/people.json?page=${this.currentPage}`
      )
        .then((response) => response.json())
        .then((data) => (this.people = data));
    },
  },
};
</script>

W komponencie PeopleTable, używamy funkcji życia komponentu created do pobrania danych z serwera przy pierwszym renderowaniu. Następnie używamy watch do monitorowania zmian wartości currentPage i pobieramy dane, gdy wartość się zmienia.

W pliku src/App.vue zaimportuj komponent PeopleTable i umieść go wewnątrz szablonu:

<template>
  <div id="app">
    <PeopleTable />
  </div>
</template>

<script>
import PeopleTable from "./components/PeopleTable.vue";

export default {
  name: "App",
  components: {
    PeopleTable,
  },
};
</script>

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Teraz, gdy uruchomisz aplikację, zobaczysz tabelę z danymi i paginację zarządzaną przez komponent PeopleTable oparty na Vue.js. Vue.js oferuje wiele narzędzi i funkcji, które ułatwiają tworzenie aplikacji opartych na komponentach, a także zarządzanie stanem i interfejsem użytkownika.

Podsumowanie

W artykule omówiliśmy trzy podejścia do paginacji w SPA: jQuery, React.js i Vue.js. Każde ma wady i zalety. Wybór zależy od wielu czynników.

  • Skala projektu: jQuery dla prostych, React.js i Vue.js dla większych i bardziej złożonych projektów. Architektura oparta na komponentach ułatwia zarządzanie kodem.
  • Wielkość biblioteki i wydajność: jQuery jest lekkie, ale mniej wydajne. Vue.js jest lżejszy od React.js, co ma znaczenie dla transferu danych.
  • Krzywa uczenia się: jQuery łatwe do nauki, React.js z większym wsparciem społeczności. Vue.js uważany za prostszy od React.js.
  • Ekosystem i społeczność: React.js ma bogaty ekosystem, Vue.js również z dużym wsparciem. jQuery traci na znaczeniu na rzecz nowszych frameworków.
  • Wsparcie dla SEO: jQuery łatwiejsze do indeksowania, React.js i Vue.js oferują server-side rendering dla lepszego SEO.
  • Długoterminowe wsparcie i aktualizacje: React.js wspierany przez Facebooka, Vue.js aktywne wsparcie twórcy i społeczności. jQuery mniej rozwijane.
  • Integracja z innymi technologiami: React.js i Vue.js łatwiej integrują się z innymi narzędziami. jQuery może być bardziej ograniczone.

Wybór zależy od oczekiwań, potrzeb projektu oraz wad i zalet technologii. Kluczowe jest zrozumienie koncepcji i narzędzi, które pozwalają efektywnie zarządzać danymi i interfejsem użytkownika.

Leave a Comment

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Scroll to Top