App-Domain
Um die Art des Programmierens mit einer Mini-App zu zeigen auf eine Web-App angewendet habe, brauchte ich eine kleine, aber ausreichende Idee für eine App. Intervalltraining mit hoher Intensität (HIIT) ist eine kardiovaskuläre Trainingsstrategie, bei der abwechselnd Sätze von kurzen intensiven anaeroben Trainingseinheiten mit weniger intensiven Erholungseinheiten verwendet werden. Viele HIIT-Trainings nutzen HIIT-Timer, z. B. diese 30-minütige Onlinesitzung. vom YouTube-Kanal The Body Coach TV.
![HIIT-Online-Trainingseinheit mit grünem Timer mit hoher Intensität.](https://web.developers.google.cn/static/articles/mini-apps/mini-app-example-project/image/hiit-training-online-sess-ed5b035be1093.png?authuser=9&hl=de)
![HIIT-Online-Trainingseinheit mit einem roten Timer mit niedriger Intensität.](https://web.developers.google.cn/static/articles/mini-apps/mini-app-example-project/image/hiit-training-online-sess-a0dd5340756f1.png?authuser=9&hl=de)
Beispiel-App für HIIT-Zeit
Für dieses Kapitel habe ich ein einfaches Beispiel für eine solche HIIT-Timer-Anwendung mit dem passenden Namen erstellt. „HIIT-Zeit“ mit der der Nutzer verschiedene Timer, besteht immer aus einem Intervall mit hoher und niedriger Intensität, und dann eine davon für eine Schulung auswählen. Es ist eine responsive App mit einer Navigationsleiste, einer Tableiste und drei Seiten:
- Training:Die aktive Seite während eines Trainings. Der Nutzer kann einen der Timer auswählen. Es gibt drei Fortschrittsringe: die Anzahl der Sätze, die aktive Periode und die Ruheperiode.
- Timer:Damit werden bestehende Timer verwaltet und Nutzer können neue Timer erstellen.
- Einstellungen:Hier können Sie Soundeffekte und die Sprachausgabe umschalten sowie Sprache und Design auswählen.
Die folgenden Screenshots vermitteln einen Eindruck von der Anwendung.
<ph type="x-smartling-placeholder">App-Struktur
Wie oben beschrieben, besteht die App aus einer Navigationsleiste, einer Tableiste und drei Seiten, die in einem Raster angeordnet sind.
Die Navigationsleiste und die Tableiste sind als iFrames mit einem <div>
-Container dazwischen dargestellt, der drei weitere iFrames enthält.
für die Seiten, von denen eine immer sichtbar und abhängig von der aktiven Auswahl in der Tableiste ist.
Ein abschließender iFrame, der auf about:blank
verweist, wird für dynamisch erstellte In-App-Seiten ausgeliefert, die zum Ändern von vorhandenen
oder neue erstellen.
Ich nenne dieses Muster mehrseitige Single-Page-App (MPSPA).
![Ansicht der Chrome-Entwicklertools der HTML-Struktur der App mit sechs iFrames: einem für die Navigationsleiste, einem für die Tableiste und drei gruppierten iFrames für jede Seite der App, mit einem letzten Platzhalter-iFrame für dynamische Seiten.](https://web.developers.google.cn/static/articles/mini-apps/mini-app-example-project/image/chrome-devtools-view-the-9da043317ba5b.png?authuser=9&hl=de)
Komponentenbasiertes Lith-HTML-Markup
Die Struktur der einzelnen Seiten ist als Beleuchtetes HTML-Scaffold umgesetzt.
das zur Laufzeit dynamisch ausgewertet wird.
Im Hintergrund für Lit-HTML ist es eine effiziente, ausdrucksstarke, erweiterbare HTML-Vorlagenbibliothek für JavaScript.
Durch die direkte Verwendung in den HTML-Dateien ist das mentale Programmiermodell direkt ausgabeorientiert.
Als Programmierer schreiben Sie
eine Vorlage dafür, wie die Ausgabe
und „lit-html“ füllt die Lücken dynamisch anhand Ihrer Daten und bindet die Event-Listener ein.
Die App verwendet benutzerdefinierte Elemente von Drittanbietern wie <sl-progress-ring>
von Shoelace oder ein selbst implementiertes benutzerdefiniertes Element namens <human-duration>
.
Da benutzerdefinierte Elemente eine deklarative API haben (z. B. das Attribut percentage
des Fortschrittsrings),
sie funktionieren gut mit Lit-HTML zusammen, wie Sie in der nachfolgenden Auflistung sehen können.
<div>
<button class="start" @click="${eventHandlers.start}" type="button">
${strings.START}
</button>
<button class="pause" @click="${eventHandlers.pause}" type="button">
${strings.PAUSE}
</button>
<button class="reset" @click="${eventHandlers.reset}" type="button">
${strings.RESET}
</button>
</div>
<div class="progress-rings">
<sl-progress-ring
class="sets"
percentage="${Math.floor(data.sets/data.activeTimer.sets*100)}"
>
<div class="progress-ring-caption">
<span>${strings.SETS}</span>
<span>${data.sets}</span>
</div>
</sl-progress-ring>
</div>
![Drei Tasten und ein Fortschrittsring.](https://web.developers.google.cn/static/articles/mini-apps/mini-app-example-project/image/three-buttons-a-progress-df2f6a20c093.png?authuser=9&hl=de)
Programmiermodell
Jede Seite verfügt über eine entsprechende Page
-Klasse, die das Lit-HTML-Markup mit Leben füllt, indem sie Implementierungen bereitstellt.
der Event-Handler und Bereitstellen der Daten für jede Seite.
Diese Klasse unterstützt auch Lebenszyklusmethoden wie onShow()
, onHide()
, onLoad()
und onUnload()
.
Seiten haben Zugriff auf einen Datenspeicher, der für die Freigabe von optionalem persistenten Status pro Seite und globalem Status dient.
Alle Strings werden zentral verwaltet, sodass die Internationalisierung integriert ist.
Das Routing wird vom Browser im Wesentlichen kostenlos durchgeführt, da die Anwendung lediglich die iFrame-Sichtbarkeit ein- und
Ändern Sie bei dynamisch erstellten Seiten das Attribut src
des Platzhalter-iFrames.
Das folgende Beispiel zeigt den Code zum Schließen einer dynamisch erstellten Seite.
import Page from '../page.js';
const page = new Page({
eventHandlers: {
back: (e) => {
e.preventDefault();
window.top.history.back();
},
},
});
![In-App-Seite als iFrame realisiert.](https://web.developers.google.cn/static/articles/mini-apps/mini-app-example-project/image/in-app-page-realized-an-25ec73e15af7f.png?authuser=9&hl=de)
Stile
Der Stil von Seiten erfolgt pro Seite in einer eigenen, auf einen Bereich reduzierten CSS-Datei.
Das bedeutet, dass Elemente normalerweise
direkt über ihre Elementnamen angesprochen werden können,
da es nicht zu Konflikten mit anderen Seiten kommen kann.
Da auf jeder Seite globale Stile hinzugefügt werden, sind zentrale Einstellungen wie font-family
oder box-sizing
müssen nicht wiederholt deklariert werden.
Hier werden auch die Designs und die Optionen für den dunklen Modus definiert.
Die folgende Liste enthält die Regeln für die Seite „Einstellungen“, die die verschiedenen Formularelemente definieren.
in einem Raster.
main {
max-width: 600px;
}
form {
display: grid;
grid-template-columns: auto 1fr;
grid-gap: 0.5rem;
margin-block-end: 1rem;
}
label {
text-align: end;
grid-column: 1 / 2;
}
input,
select {
grid-column: 2 / 3;
}
![Einstellungsseite der HIIT Time App mit einem Formular im Rasterlayout.](https://web.developers.google.cn/static/articles/mini-apps/mini-app-example-project/image/hiit-app-preferences-pag-3d83359174159.png?authuser=9&hl=de)
Display-Wakelock
Während des Trainings sollte sich der Bildschirm nicht ausschalten. In Browsern, die dies unterstützen, nutzt HIIT Time dies über einen Display-Wakelock. Im Snippet unten sehen Sie, wie das funktioniert.
if ('wakeLock' in navigator) {
const requestWakeLock = async () => {
try {
page.shared.wakeLock = await navigator.wakeLock.request('screen');
page.shared.wakeLock.addEventListener('release', () => {
// Nothing.
});
} catch (err) {
console.error(`${err.name}, ${err.message}`);
}
};
// Request a screen wake lock…
await requestWakeLock();
// …and re-request it when the page becomes visible.
document.addEventListener('visibilitychange', async () => {
if (
page.shared.wakeLock !== null &&
document.visibilityState === 'visible'
) {
await requestWakeLock();
}
});
}
Anwendung testen
Die HIIT-Zeitanwendung ist auf GitHub verfügbar. Sie können die Demo jetzt in einem neuen Fenster ansehen. oder direkt in den iFrame-Einbettungscode unten ein, der ein Mobilgerät simuliert.
Danksagungen
Artikel wurde geprüft von Joe Medley, Kayce Basques Milica Mihajlija, Alan Kent, und Keith Gu.