Démarrage
Sur ce portail, Alpine.js est déjà installé. Ajoutez simplement dans le <head> de votre page :
<script src="/libs/alpine.min.js" defer></script>
Créez un fichier HTML vierge quelque part sur votre ordinateur, avec un nom comme j-aime-alpine.html.
À l'aide d'un éditeur de texte, remplissez ce fichier avec le contenu suivant :
<html>
<head>
<script src="/libs/alpine.min.js" defer></script>
</head>
<body>
<h1 x-data="{ message: 'Je ❤️ Alpine' }" x-text="message"></h1>
</body>
</html>
Ouvrez votre fichier dans un navigateur web. Si vous voyez Je ❤️ Alpine, vous êtes prêt à vous lancer !
Maintenant que tout est en place pour expérimenter, voyons trois exemples pratiques qui serviront de base pour apprendre les fondamentaux d'Alpine. À la fin de cet exercice, vous serez largement équipé pour commencer à construire vos propres composants. C'est parti !
- Construire un compteur
- Construire un menu déroulant
- Construire un champ de recherche
Construire un compteur
Commençons par un « compteur » simple pour illustrer les bases de l'état et de l'écoute d'événements dans Alpine, deux fonctionnalités essentielles.
Insérez le code suivant dans la balise <body> :
<div x-data="{ count: 0 }">
<button x-on:click="count++">Incrémenter</button>
<span x-text="count"></span>
</div>
Vous voyez qu'avec seulement 3 touches d'Alpine saupoudrées dans ce HTML, nous avons créé un composant « compteur » interactif.
Passons brièvement en revue ce qui se passe.
Déclarer des données
<div x-data="{ count: 0 }">
Tout, dans Alpine, commence par une directive x-data. À l'intérieur de x-data, vous déclarez en JavaScript pur un objet de données qu'Alpine va suivre.
Chaque propriété de cet objet sera mise à la disposition des autres directives situées à l'intérieur de cet élément HTML. De plus, lorsqu'une de ces propriétés change, tout ce qui en dépend change aussi.
Remarque :
x-dataest requis sur un élément parent pour que la plupart des directives d'Alpine fonctionnent.
Regardons maintenant x-on et voyons comment il peut accéder à la propriété count et la modifier :
Écouter des événements
<button x-on:click="count++">Incrémenter</button>
x-on est une directive qui permet d'écouter n'importe quel événement sur un élément. Ici, nous écoutons un événement click, d'où x-on:click.
Vous pouvez bien sûr écouter d'autres événements. Par exemple, écouter un événement mouseenter s'écrirait x-on:mouseenter.
Lorsqu'un événement click se produit, Alpine appelle l'expression JavaScript associée, count++ dans notre cas. Comme vous le voyez, nous avons un accès direct aux données déclarées dans l'expression x-data.
Remarque : Vous verrez souvent
@à la place dex-on:. C'est une syntaxe plus courte et plus conviviale que beaucoup préfèrent. Désormais, cette documentation utilisera généralement@au lieu dex-on:.
Réagir aux changements
<span x-text="count"></span>
x-text est une directive Alpine qui définit le contenu textuel d'un élément à partir du résultat d'une expression JavaScript.
Ici, nous demandons à Alpine de toujours faire en sorte que le contenu de cette balise span reflète la valeur de la propriété count.
Au cas où ce ne serait pas clair : x-text, comme la plupart des directives, accepte une simple expression JavaScript. Vous pourriez par exemple écrire x-text="count * 2" et le contenu du span serait alors toujours égal à 2 fois la valeur de count.
Construire un menu déroulant
Maintenant que nous avons vu quelques fonctionnalités de base, continuons avec une directive importante d'Alpine, x-show, en construisant un composant « menu déroulant » volontairement simple.
Insérez le code suivant dans la balise <body> :
<div x-data="{ open: false }">
<button @click="open = ! open">Afficher/masquer</button>
<div x-show="open" @click.outside="open = false">Contenu...</div>
</div>
Si vous chargez ce composant, vous verrez que « Contenu... » est masqué par défaut. Vous pouvez l'afficher ou le masquer en cliquant sur le bouton « Afficher/masquer ».
Les directives x-data et x-on vous sont déjà familières depuis l'exemple précédent ; nous ne les réexpliquons donc pas.
Afficher et masquer des éléments
<div x-show="open" ...>Contenu...</div>
x-show est une directive extrêmement puissante d'Alpine : elle permet d'afficher ou de masquer un bloc de HTML selon le résultat d'une expression JavaScript, ici open.
Écouter un clic à l'extérieur
<div ... @click.outside="open = false">Contenu...</div>
Vous remarquerez quelque chose de nouveau dans cet exemple : .outside. De nombreuses directives d'Alpine acceptent des « modificateurs » ajoutés à la fin de la directive et séparés par des points.
Ici, .outside indique à Alpine de ne pas écouter un clic À L'INTÉRIEUR du <div>, mais de réagir uniquement si le clic se produit À L'EXTÉRIEUR du <div>.
C'est une aide intégrée à Alpine, car ce besoin est fréquent et l'implémenter à la main est fastidieux et complexe.
→ En savoir plus sur les modificateurs de x-on
Construire un champ de recherche
Construisons maintenant un composant plus complexe, qui présente quelques autres directives et motifs courants.
Insérez le code suivant dans la balise <body> :
<div
x-data="{
search: '',
items: ['foo', 'bar', 'baz'],
get filteredItems() {
return this.items.filter(
i => i.startsWith(this.search)
)
}
}"
>
<input x-model="search" placeholder="Rechercher...">
<ul>
<template x-for="item in filteredItems" :key="item">
<li x-text="item"></li>
</template>
</ul>
</div>
Par défaut, tous les éléments (foo, bar et baz) sont affichés sur la page, mais vous pouvez les filtrer en tapant dans le champ de texte. Au fil de votre saisie, la liste se met à jour pour refléter votre recherche.
Il se passe pas mal de choses ici ; examinons cet extrait morceau par morceau.
Mise en forme sur plusieurs lignes
La première chose à noter est que x-data contient maintenant beaucoup plus de code qu'avant. Pour faciliter l'écriture et la lecture, nous l'avons réparti sur plusieurs lignes dans notre HTML. C'est tout à fait facultatif, et nous verrons plus tard comment éviter complètement ce problème, mais pour l'instant nous gardons tout ce JavaScript directement dans le HTML.
Lier des champs de saisie
<input x-model="search" placeholder="Rechercher...">
Vous remarquerez une nouvelle directive : x-model.
x-model sert à « lier » la valeur d'un champ de saisie à une propriété de données : ici, « search » de x-data="{ search: '', ... }".
Cela signifie que chaque fois que la valeur du champ change, la valeur de « search » change aussi pour la refléter.
x-model est capable de bien plus que cet exemple simple.
Propriétés calculées avec des getters
Attardons-nous maintenant sur les propriétés items et filteredItems de la directive x-data.
{
...
items: ['foo', 'bar', 'baz'],
get filteredItems() {
return this.items.filter(
i => i.startsWith(this.search)
)
}
}
La propriété items se comprend d'elle-même : nous lui donnons pour valeur un tableau JavaScript de 3 éléments (foo, bar et baz).
La partie intéressante de cet extrait est la propriété filteredItems.
Grâce au préfixe get, filteredItems est une propriété « getter » de cet objet. Cela signifie que nous pouvons accéder à filteredItems comme à une propriété normale de notre objet de données, mais qu'en coulisses JavaScript évalue la fonction fournie et renvoie son résultat.
Vous pouvez tout à fait vous passer de get et en faire une simple méthode appelable depuis le template, mais certains préfèrent la syntaxe plus agréable du getter.
→ En savoir plus sur les getters JavaScript
Regardons maintenant l'intérieur du getter filteredItems pour bien comprendre ce qui s'y passe :
return this.items.filter(
i => i.startsWith(this.search)
)
Il s'agit de JavaScript pur. Nous récupérons d'abord le tableau d'éléments (foo, bar et baz) et nous le filtrons avec la fonction de rappel fournie : i => i.startsWith(this.search).
En passant cette fonction à filter, nous demandons à JavaScript de ne renvoyer que les éléments qui commencent par la chaîne this.search qui, comme nous l'avons vu avec x-model, reflète toujours la valeur du champ.
Vous avez peut-être remarqué que jusqu'ici nous n'avions pas eu besoin d'écrire this. pour référencer les propriétés. Cependant, comme nous travaillons directement à l'intérieur de l'objet x-data, nous devons référencer chaque propriété avec this.[propriété] et non simplement [propriété].
Alpine étant un framework « réactif », chaque fois que la valeur de this.search change, les parties du template qui utilisent filteredItems sont automatiquement mises à jour.
Parcourir des éléments en boucle
Maintenant que nous comprenons la partie données de notre composant, voyons ce qui se passe dans le template pour parcourir filteredItems sur la page.
<ul>
<template x-for="item in filteredItems">
<li x-text="item"></li>
</template>
</ul>
Il faut d'abord remarquer la directive x-for. Les expressions x-for ont la forme [item] in [items], où [items] est un tableau de données quelconque et [item] le nom de la variable qui recevra l'élément courant à chaque itération de la boucle.
Remarquez aussi que x-for est déclaré sur un élément <template> et non directement sur le <li>. C'est une obligation avec x-for : cela permet à Alpine de tirer parti du comportement existant des balises <template> dans le navigateur.
Tout élément placé dans la balise <template> sera répété pour chaque élément de filteredItems, et toutes les expressions évaluées dans la boucle ont un accès direct à la variable d'itération (item ici).
Récapitulatif
Si vous êtes arrivé jusqu'ici, vous avez découvert les directives Alpine suivantes :
- x-data
- x-on
- x-text
- x-show
- x-model
- x-for
C'est un excellent début, mais il reste beaucoup d'autres directives à découvrir. La meilleure façon d'assimiler Alpine est de parcourir cette documentation. Inutile de lire chaque mot, mais si vous parcourez au moins chaque page, vous serez BEAUCOUP plus efficace dans votre utilisation d'Alpine.
Bon code !
Traduction française de la documentation officielle d'Alpine.js (licence MIT) – https://alpinejs.dev