Ionic

In der klassischen Multiplattformentwicklung musste für jede Plattform eine Codebasis mit entsprechend spezialisierten Entwicklern unterhalten werden. Dies kann unteranderem sehr ressourcenintensiv werden. Dieser Artikel stellt das Toolkit Ionic (Ionic, 2021a) vor, welches die zuvor genannten Probleme angeht. Als Erstes wird eine Einführung in das Toolkit selbst gegeben. Dieses wird gefolgt von den Anforderungen an die Entwicklungsumgebung. Danach wird die Erstellung eines Prototypen mittels Ionic vorgestellt. Dieser Prototyp wird in den darauffolgenden Abschnitten für Android und Windows gebuilded. Zum Schluss werden Vor- und Nachteile von Ionic vorgestellt.

Dieser Artikel ist Teil einer Reihe von Artikeln, in welchen verschiedene Frameworks für die Multiplattform-Entwicklung vorgestellt werden:

Was ist Ionic

Ionic ist ein open-source Toolkit unter der MIT Lizenz, welches das Bedienen mehrerer Plattformen, insbesondere mobile Plattformen und das Web ermöglicht (Ionic, 2021a). Dadurch muss nur eine Codebasis gepflegt werden. Gleichzeitig werden Webtechnologien verwendet, um eine App zu erstellen. Während der Entwicklung kann entweder lokal in einem Browser oder emulierten Gerät oder per WLAN (Ionic, 2021c) getestet werden. Ein sinnbildlicher Aufbau von Ionic wird in der folgenden Abbildung 1 präsentiert:

Abbildung 1: Veranschaulichung des Aufbaus von Ionic.

Im Kern von Ionic sind Komponenten, aus welchen das UI zusammengesetzt wird. Dafür bietet Ionic eine Bibliothek grundlegender UI Bausteine an (Ionic, 2021b). Die Erstellung der App wird mittels Webtechnologien (HTMl, CSS und JavaScript) getätigt. Für das Frontend bietet Ionic Templates Angular (Angular, 2021), React (React, 2021) und Vue (Vue, 2021) an. Das erstellte webbasierte UI wird in einer Webview angezeigt. Diese ist wiederum in Capacitor (Capacitor, 2021) eingebettet. Bei Capacitor handelt es sich um eine native Laufzeitumgebung, in der die App läuft. Dabei dient Capacitor als Verbindung zwischen App und der Zielplattform. Um native Funktionalitäten hinzuzufügen, können Plugins in der jeweiligen nativen Sprache integriert werden.

Styling

Da Webtechnologien verwendet werden, können Komponenten mittels CSS gestyled werden. Jedoch existieren die folgenden Besonderheiten dabei (Carney, 2020):

    • Für das globale Theming werden CSS-Variablen in der Datei css definiert. Für Anpassungen des Themes müssen die Variablen in dieser Datei angepasst werden.
    • Für das Styling von Ionic-Komponenten bieten diese selbst Variablen an, welche genutzt werden können. Ein exemplarisches Styling wird in der folgenden Abbildung präsentiert:
      ion-button {
        --background: var(--ion-color-primary);
      }
      

      Abbildung 2: Styling eines IonButtons über seine Variablen.

    • Die von Ionic angebotenen Komponenten sind Wrapper für HTML-Elemente, welche den Shadow DOM ausmachen. Das Styling dieser Elemente ist in sich gekapselt, um somit Seiteneffekte von Styles auf andere Teile des Interfaces zu vermeiden. Zum Stylen dieser Elemente werden parts verwendet. Dies wird in Abbildung 3 präsentiert
      ion-button::part(native) {
        border: 5px dashed var(--ion-color-warning);
      }
      

      Abbildung 3: Styling des Shadow DOMs eines IonButtons.

Anforderungen

Damit mit Ionic entwickelt und das Ergebnis deployed werden kann, wird die folgende Software benötigt:

Initialisierung des Prototypen

Bis jetzt wurde Ionic nur theoretisch besprochen. Um jedoch ein detaillierteres Verständnis vom Toolkit zu erhalten, wird ein Prototyp erstellt. Dieser soll drei Seiten umfassen, wobei jede Seite einen anderen Aspekt von Ionic präsentiert: Die Index-Seite soll die von Ionic zur Verfügung gestellten Hooks und CSS-Variablen präsentieren. Die User-Seite soll die Basis-Komponenten von Ionic sowie verschiedene Ansätze für das Styling beinhalten. Die letzte Seite ist die Hilfe-Seite, welche mehrere Ansätze für Animationen präsentieren soll. In Abbildung 4 werden die drei resultierenden Ansichten dargestellt.

Abbildung 4: Die drei resultierenden Ansichten: Index (links), Users (Mitte) und Hilfe (rechts).

Um das Projekt zu erstellen, werden die folgenden Befehle ausgeführt:

# install cli globaly
$ npm i -g @ionic/cli
# create Project with react
$ ionic start hello_ionic blank –type react -capacitor
$ cd hello_ionic
# set up debugging via wlan
$ ionic serve –external –host=192.168.178.86 –port=9123

Abbildung 5: Befehle zum Erstellen eines Ionic Projektes mit Debugging via WLAN.

Nachdem diese Befehle ausgeführt wurden, kann ein Endgerät über die spezifizierte Adresse mit dem Dev-Server verbinden. Zusätzlich werden Änderungen via Hot Reload automatisch auf dem Endgerät angezeigt.

Erstellung der Index-Seite

Die Index-Seite soll nur einen Schriftzug mit einer Hintergrundfarbe beinhalten. Dabei wird eine Hintergrundfarbe aus den globalen CSS-Variablen ausgewählt. Gleichzeitig wird einer der von Ionic zur Verfügung gestellter Hooks, der UseIonViewDidEnter Hook, präsentiert. Dieser Hook wird aktiviert, wenn im Lifecycle der Komponente das Routing beendet wurde (Ionic, 2021d). In Abbildung 6 wird der Code der Seite präsentiert.

import { useIonViewDidEnter } from "@ionic/react";
import { useState } from "react";
 
export default function IndexPage() {
  const [backgroundColor, setBackgroundColor] = useState(
    "var(--ion-color-success-tint)"
  );
 
  useIonViewDidEnter(() => setBackgroundColor("var(--ion-color-warning)"));
 
  return <h1 style={{ backgroundColor }}>Index Page</h1>;
}

Abbildung 6: Code der index-page.tsx.

Erstellung der User-Seite

Diese Seite soll eine Liste von Nutzern anzeigen sowie die Möglichkeit zum Hinzufügen eines Users bieten. Dafür wird ein Array von Usern im State und eine Funktion zum Hinzufügen eines Users definiert. Im Template werden die Komponenten UserForm und UserList integriert und es werden die Props and die Komponenten übergeben. Gleichzeitig werden diese beiden Komponenten in der Ionic-Komponente IonCol eingefügt, sodass die Komponenten untereinander angezeigt werden. Die Präsentation des Codes ist in Abbildung 7 zu finden.

import { IonCol } from "@ionic/react";
import React, { useState } from "react";
 
import UserForm from "../components/user-form/user-form";
import UserList from "../components/users-list/users-list";
import IUser from "../model/user.model";
 
export default function UsersPage(): React.ReactElement {
  const [users, setUsers] = useState<IUser[]>([
    { id: 1, name: "Jürgen" },
    { id: 2, name: "Hans" },
    { id: 3, name: "Peter" },
  ]);
 
  function addUser(user: IUser) {
    setUsers([...users, user]);
  }
 
  return (
    <>
      <IonCol>
        <UserForm addUser={addUser}></UserForm>
        <UserList users={users}></UserList>
      </IonCol>
    </>
  );
}

Abbildung 7: Code der user-page.tsx.

Die UserList-Komponente

Diese Komponente soll eine Liste von Nutzern, die als Prop übergeben werden, darstellen. Für die Liste wird die Komponente IonList verwendet. In diese wird für jeden User ein IonItem mit Bild und Name eingebettet. Hierbei lässt sich eine semantische Hierarchie zwischen Ionic-Komponenten ableiten, die der Hierarchie herkömmlicher HTML-Listen ähnelt. Gleichzeitig zeigt diese Komponente auf, dass CSS ohne Probleme importiert und verwendet werden kann. Die folgende Abbildung zeigt den Code für die beschriebene Komponente:

import { IonImg, IonItem, IonLabel, IonList } from "@ionic/react";
import React from "react";
import IUser from "../../model/user.model";
 
import styles from "./users-list.module.css";
 
export default function UsersList(props: {
  users: IUser[];
}): React.ReactElement {
  function renderUserName(user: IUser) {
    return (
      <IonItem className={styles["list-item"]} key={user.id}>
        <IonImg
          className={styles.leading}
          src="https://source.unsplash.com/random"
          alt="leading of the item"
        />
        <IonLabel>{user.name}</IonLabel>
      </IonItem>
    );
  }
 
  return <IonList>{props.users.map((user) => renderUserName(user))}</IonList>;
}

Abbildung 8: Code der user-list.tsx

Die UserForm-Komponente

Diese Komponente besteht nicht nur aus einer TSX-Datei sondern auch aus einer CSS-Datei. In der TSX-Datei wird ein IonGrid, welches als ein Wrapper für IonCol und IonRows agiert, verwendet. Beim Grid handelt es sich um ein Flexbox basiertes Layout. Das Layout beinhaltet zwei Zeilen: eine für das Erstellen eines Users und eine für ein Label. Der Code wird in der folgenden Abbildung präsentiert:

import {
  IonCol,
  IonGrid,
  IonLabel,
  IonRow,
  IonInput,
  IonItemDivider,
  IonButton,
} from "@ionic/react";
import React, { useState } from "react";
import IUser from "../../model/user.model";
 
import styles from "./user-form.module.css";
 
export default function UserForm(props: {
  addUser: (user: IUser) => void;
}): React.ReactElement {
  const [insertedName, setInsertedName] = useState("");
 
  function handleSubmit() {
    const newUser = {
      id: Math.floor(Math.random() * 1000000),
      name: insertedName,
    } as IUser;
    props.addUser(newUser);
    setInsertedName("");
  }
 
  return (
    <IonGrid>
      <IonCol>
        <IonLabel>Add a User:</IonLabel>
        <IonRow className={styles["input-container"]}>
          <IonItemDivider>
            <IonInput
              type="text"
              inputmode="text"
              value={insertedName}
              placeholder="Enter A User"
              onIonChange={(e) => setInsertedName(e.detail.value!)}
            />
          </IonItemDivider>
          <IonButton
            title="Add User"
            onClick={handleSubmit}
            className={styles["custom-button"]}
          >
            Add User
          </IonButton>
        </IonRow>
      </IonCol>
    </IonGrid>
  );
}

Abbildung 9: Code der user-form.tsx

Der interessante Teil dieser Komponente ist das Styling des IonButtons über die CSS-Datei. Als Erstes wird die Hintergrundfarbe des IonButtons über eine seiner CSS-Properties geändert. Dafür wird –background verwendet, welche mit der global definierten primären Farbe gesetzt wird. Dieses Styling wird auf alle IonButtons angewendet, die in der Komponente integriert sind. Um dies zu vermeiden, kann der Shadow DOM (der „versteckte“ Inhalt einer Komponente) direkt gestyled werden. Der Shadow DOM einer Komponente kann aus mehreren Teilen (Parts) bestehen. Mittels des Part-Selektoren können diese gestyled werden. In diesem Beispiel wird der Part native des IonButtons ausgewählt und es wird dessen Hintergrund beim Hovern gestyled. In diesem Fall besitzt der Button nur ein Part. Jedoch kann es vorkommen, dass eine Ionic-Komponente mehrere Parts anbietet. Eine Liste der Parts kann in der Ionic-Dokumentation gefunden werden. Die folgende Abbildung präsentiert den relevanten Code:

.input-container {
  flex-wrap: nowrap;
}

.custom-button {
  border-radius: 50px;
  color: white;
}

/* Component Property */
ion-button {
  --background: var(--ion-color-primary);
}

/* Shadow DOM */
ion-button.custom-button::part(native):hover {
  background-color: var(--ion-color-warning);
}

Abbildung 10: CSS-Code user-form.module.css.

Erstellung der Hilfe-Seite

Diese Seite soll einen animierten Text beinhalten. Dafür wurden zwei Ansätze verwendet: Ein einfacher JavaScript und ein komponentenbasierter Ansatz. Der Code wird in der folgenden Abbildung vorgestellt:

import {
  IonContent,
  IonText,
  CreateAnimation,
  createAnimation,
} from "@ionic/react";
import React, { useEffect, useRef } from "react";
 
export default function HelpPage(): React.ReactElement {
  const contentRef = useRef(null);
 
  useEffect(() => {
    createAnimation()
      .addElement(contentRef.current!)
      .duration(2000)
      .fromTo("transform", "translateY(0px)", "translateY(250px)")
      .fromTo("width", "0%", "100%")
      .play();
  }, []);
 
  return (
    <IonContent ref={contentRef}>
      <CreateAnimation
        duration={5000}
        iterations={Infinity}
        easing="ease-out"
        keyframes={[
          {
            offset: 0,
            opacity: "0",
            color: "green",
          },
          {
            offset: 0.5,
            opacity: "1",
            color: "green",
          },
          {
            offset: 1,
            opacity: "1",
            color: "orange",
          },
        ]}
        play={true}
      >
        <IonText>
          Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
          nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.
        </IonText>
      </CreateAnimation>
    </IonContent>
  );
}

Abbildung 11: Code der Hilfe-Seite help-page-tsx.

Die Animation des reinen JavaScripts soll gleichzeitig die vertikale Position des Textes sowie die Breite modifizieren. Dafür wird im useEffect-Hook eine Animation instanziiert. Dieser wird als Ziel-Element der Container der Animation, eine Zeit von zwei Sekunden und mehrere Animationen von Styles übergeben. Die Animationen werden in der Methode FromTo definiert. Dabei wird der Name des Styles sowie ein Start- und Endwert übergeben. In diesem Beispiel wird als Erstes transform mit translateY von 0px bis 250px übergeben. Darauf folgt width mit einem Startwert von 0% hin zu einem Endwert von 100%. Zum Schluss wird die Methode Play verwendet, um die Animation zu starten.

Für die zweite Animation wird die von Ionic angebotene Komponente CreateAnimation verwendet. Dieser Komponente bekommt relevante Werte als Props übergeben. Diese Animation soll 5 Sekunden dauern, sich endlos wiederholen und gegen Ende langsamer werden. Entsprechend werden die Props duration, iterations und easing gesetzt. Zusätzlich wird ein Array von Keyframes an die Komponente übergeben, die die eigentlichen Änderungen beschreiben. Im Intervall [0%, 50%] der Animation soll der Text Grün sein. Danach soll im Intervall [50%, 100%] die Farbe zu Orange geändert werden. Gleichzeitig soll sich in den beschriebenen Intervallen die Opazität von 0 auf 1 ändern.

Beim Mounten der Komponente werden die Animationen automatisch parallel abgespielt und dessen Ergebnis sieht wie folgt aus:

Abbildung 12: Darstellung der Animationen auf der Hilfe-Seite.

Komposition der Seiten

Da der Prototyp nun drei Seiten besitzt, soll zwischen diesen auch navigiert werden können. Dafür wird Routing benötigt. Gleichzeitig soll das Layout für alle konsistent sein, um somit den Eindruck einer App zu erwecken. Daher wird in den folgenden Abschnitten jeweils das Layout und Routing beschrieben.

Layout

Das Layout besteht aus einer IonPage, die wiederum aus einem IonHeader und IonContent besteht. Die Komponente erhält als Props die anzuzeigende Seite, welche im IonContent eingebettet wird. Der IonHeader besteht aus einer IonToolbar, welche Buttons für die Navigation und einen Titel beinhaltet. Die Buttons und der Titel werden in der Toolbar anhand ihres zugewiesenen Slots gerendert. Beispielsweise werden die Buttons zum Aufrufen der User- und Hilfe-Seite am Ende der Toolbar gerendert. Zusätzlich werden die Buttons für das Navigieren abhängig der Route gerendert. Analog wird der Titel in der Toolbar abhängig der Route gesetzt. Dafür wird bei jeder Änderung der Route im useEffect-Hook der Titel neu berechnet. Die folgende Abbildung präsentiert den Code des beschriebenen Layouts:

import {
  IonBackButton,
  IonButton,
  IonButtons,
  IonContent,
  IonHeader,
  IonIcon,
  IonPage,
  IonTitle,
  IonToolbar,
} from "@ionic/react";
import { helpOutline, peopleOutline } from "ionicons/icons";
import { useLocation } from "react-router";
import React, { useEffect, useState } from "react";
 
ex-port default function DefaultLayout(props: { children: React.ReactElement }) {
  const location = useLocation();
  const [titleText, setTitleText] = useState("Hello Ionic");
 
  useEffect(() => {
    let newTitle = "Hello Ionic";
    if (location.pathname === "/users") {
      newTitle = "Users";
    }
    if (location.pathname === "/help") {
      newTitle = "Help";
    }
    setTitleText(newTitle);
  }, [location.pathname]);
 
  return (
    <IonPage>
      <IonHeader>
        <IonToolbar>
          <IonTitle slot="primary" style={{ textAlign: "center" }}>
            {titleText}
          </IonTitle>
          {location.pathname !== "/" && (
            <IonButtons slot="start">
              <IonBackButton defaultHref="/" text=""></IonBackButton>
            </IonButtons>
          )}
          {location.pathname === "/" && (
            <IonButtons slot="end">
              <IonButton routerLink="/users" slot="icon-only">
                <IonIcon
                  icon={peopleOutline}
                  slot="icon-only"
                  color="primary"
                ></IonIcon>
              </IonButton>
              <IonButton routerLink="/help" slot="icon-only">
                <IonIcon
                  icon={helpOutline}
                  slot="icon-only"
                  color="primary"
                ></IonIcon>
              </IonButton>
            </IonButtons>
          )}
        </IonToolbar>
      </IonHeader>
      <IonContent fullscreen>{props.children}</IonContent>
    </IonPage>
  );
}

Abbildung 13: Layout-Code in der default-layout.tsx.

Routing

Damit die erstellten Seiten angezeigt werden können, wird der IonReactRouter, welcher auf dem ReactRouter aufbaut, verwendet. Jede Seite wird dabei in das zuvor präsentierte Layout eingebettet und unter der gewünschten Route verfügbar gemacht. Abbildung 14 präsentiert den Code für das Routing.

import { Route } from "react-router-dom";
import { IonApp, IonRouterOutlet } from "@ionic/react";
import { IonReactRouter } from "@ionic/react-router";
 
/* Ionic CSS imports*/
 
import DefaultLayout from "./layout/default-layout";
import IndexPage from "./pages/index-page";
import UsersPage from "./pages/users-page";
import HelpPage from "./pages/help-page";
 
const App: React.FC = () => (
  <IonApp>
    <IonReactRouter>
      <IonRouterOutlet>
        <Route exact path="/">
          <DefaultLayout>
            <IndexPage></IndexPage>
          </DefaultLayout>
        </Route>
        <Route exact path="/users">
          <DefaultLayout>
            <UsersPage></UsersPage>
          </DefaultLayout>
        </Route>
        <Route exact path="/help">
          <DefaultLayout>
            <HelpPage></HelpPage>
          </DefaultLayout>
        </Route>
        {/* default page */}
        <Route>
          <DefaultLayout>
            <IndexPage></IndexPage>
          </DefaultLayout>
        </Route>
      </IonRouterOutlet>
    </IonReactRouter>
  </IonApp>
);
 
export default App;

Abbildung 14: Code der app.tsx für das Routing.

Builden für Android

Bis jetzt ist der Prototyp nur im Browser lauffähig. Jedoch soll auch eine andere Plattform, in diesem Fall Android bedient werden. Hierfür wurde sich an der Dokumentation von Ionic orientiert und die folgenden Schritte durchgeführt:

  1. Über die Ionic CLI wurde der Befehl $ ionic capacitor build android ausgeführt. Dieser kopiert die web Assets in den Android Ordner und öffnet Android Studio.
  2. In Android wurde das Projekt über die folgende Menü-Hierarchie: build / build bundle(s) / APK(s) / Build APKs

Nachdem der Build in Android Studio ohne Fehler durchgelaufen ist, wird eine APK ausgegeben, die auf einem Gerät installiert wird.

Builden für Windows

Für das Builden einer Windows App wird Windows 10 und ein entsprechendes Windows-SDK benötigt. Sind diese Voraussetzungen gegeben, können die folgenden Befehle im Root-Ordner ausgeführt werden:

$ npm install electron -D
$ npm install electron-packager -D
$ tsc
$ npx electron-packager ./dist hello_ionic_windows –platform=win32

Abbildung 15: Befehlen zum Builden einer EXE.

Vor- und Nachteile

Ionic bietet Vorteile bei der Entwicklung. Jedoch ist es wie bei jeder Technologie, dass auch Nachteile vorhanden sind. In diesem Abschnitt werden Vor- und Nachteile von Ionic präsentiert:

Vorteile

  • Da Ionic die Webtechnologien HTML, CSS und JavaScript verwendet und es sich bei diesen Technologien um die am meisten verbreiteten handelt (Stackoverflow, 2021), ist es nicht unwahrscheinlich, dass die Entwickler diese Technologien schon kennen und deshalb kein weiteres Training benötigen.
  • Ionic unterstützt neben reinem JavaScript auch die populären Webframeworks Vue, React und Angular. Aufgrund er Verbreitung dieser Frameworks (Stackoverflow, 2021) müssen Entwickler nicht zwangsweise entsprechend geschult werden.
  • Mit einer Codebasis können gleichzeitig mehrere Plattformen bedient werden, sodass nur ein Team statt mehrere eingesetzt werden können.

Nachteile

  • Es kann vorkommen, dass für einen Anwendungsfall kein Plugin existiert. Wenn dieser Fall eintritt, muss ein spezialisierter Entwickler, der den benötigten nativen Code schreibt, konsultiert werden.
  • Ionic Apps laufen in einer Webview, sodass zum Darstellen der Inhalte ähnliche Schritte wie bei Browsern durchgeführt werden müssen. Dies kann dazu führen, dass bei aufwendigen Berechnungen wie bei AR oder VR Probleme in der Performance auftreten können.
  • Es besteht die Möglichkeit Ionic Premium Lizenzen zu erwerben, welche unteranderem Zugang zu einer eigenen Cloud Plattform für das Builden beinhaltet. Jedoch verbirgt sich hinter der Paywall das Angebot einiger offizieller Plugins von der Firma hinter Ionic sowie die bevorzugte Behandlung beim Support (Ionic, 2021e).

Fazit

Durch Ionic können mehrere Plattformen gleichzeitig mit Webtechnologien bedient werden. Dabei verwendet Ionic einen komponentenbasierten Ansatz und bietet nahtlose Integrationen für die gängigsten komponentenbasierten Frontendframeworks an. Durch diese Technologien ist eine flüssige Einarbeitung möglich. Bei diesem Prozess spielte die Dokumentation eine große Rolle. Die Dokumentation von Ionic beschreibt ausführlich die Aspekte des Frameworks. Bei der Vorstellung der vom Framework angebotenen Komponenten werden diese textlich beschrieben und es wird in der Regel ein Codesnippet für die verschiedene Frontendframeworks angeboten. Jedoch gibt es keine interaktiven Beispiele, mit denen eine Komponente erkundet werden kann. Zum Erstellen des Prototypen wurde React verwendet. Dadurch lassen sich auf React zugeschnittene MSAl und Fluent UI Pakete ebenfalls integrieren. Während der Entwicklung kann entweder ein Browser oder ein Endgerät per USB oder WLAN verwendet werden, wobei dank des Hot Reloads Änderungen umgehend sichtbar werden. Die Zielplattformen für Ionic sind primär das Web sowie Android und iOS basierte Geräte. Um Desktops bedienen zu können, muss sich an Elektron bedient werden. Letztendlich kann es zu großen Unterschieden beim Prozess des Builden für die Plattformen kommen. Während das Builden für Android sehr einfach ist, wird für Windows viel Konfigurationsaufwand und Trial and Error benötigt.

Referenzen

Android Studio (2021). https://developer.android.com/studio. (Stand: 06.10.2021).

Angular (2021). https://angular.io/. (Stand: 06.10.2021).

Capacitor (2021). https://capacitorjs.com/docs. (Stand: 06.10.2021).

Carney, B. (2020, August 31). Theming & customization with Ionic. Logrocket. https://blog.logrocket.com/theming-customization-with-ionic/. (Stand: 06.10.2021).

Ionic (2021a). https://ionicframework.com/. (Stand: 06.10.2021).

Ionic (2021b). https://ionicframework.com/docs/components. (Stand: 06.10.2021).

Ionic (2021c). https://ionicframework.com/docs/cli/commands/serve. (Stand: 06.10.2021).

Ionic (2021d). https://ionicframework.com/docs/react/lifecycle. (Stand: 06.10.2021).

Ionic (2021e). https://ionic.io/enterprise. (Stand: 06.10.2021).

Node (2021). https://nodejs.org/en/. (Stand: 06.10.2021).

NPM (2021). https://www.npmjs.com/. (Stand: 06.10.2021).

React (2021). https://reactjs.org/. (Stand: 06.10.2021).

Stackoverflow (2021, Juni 15). https://insights.stackoverflow.com/survey/2021#technology-most-popular-technologies. (Stand: 06.10.2021).

Visual Studio Code (2021). https://code.visualstudio.com/. (Stand: 06.10.2021).

Vue (2021). https://vuejs.org/. (Stand: 06.10.2021).

Leave a comment

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Time limit is exhausted. Please reload the CAPTCHA.