Alpine.js sur un exemple concret

Vous avez peut-être déjà entendu parler d'Alpine.js. Sinon, c'est "Vue.js au minimum". «Angular 1 for Millennials». Appelez ça comme vous voulez, la principale chose que vous comprenez.


Pourquoi avons-nous besoin d'un autre cadre? Eh bien, Alpine s'intègre bien dans sa niche. En fait, c'est une alternative aux grands cadres pour les sites où ces grands cadres ne sont pas nécessaires. Par exemple, moi, un développeur Web à la mode, a été mobilisé pour écrire un site de plusieurs pages. J'ai besoin de rendre un formulaire élémentaire et tout autre interactif. Que vais-je faire? Je vais prendre jQuery - les amis ne comprennent pas, sur l'écriture JS pure, tout n'est pas comme il faut. De plus, je connais déjà les réactions, les angles et la vue, je sais ce qu'est une approche basée sur les données. Comment puis-je maintenant stocker des données avant d'envoyer en HTML?


Ici Alpine.js vient à la rescousse. Vous pouvez bien sûr visser Vue ou React. Mais React sans JSX, personne d'esprit n'écrira, et Vue minifié via CDN pèse 34 Ko (contre 8,1 Ko pour Alpine). Il s'avère donc que le choix revient à Alpine.


Récemment, ici, sur Habré, il y avait déjà des articles de familiarisation sur Alpine.js . Mis à part le fait que le site supprimait partout les références à la balise de modèle, les articles se sont avérés assez bons.


Afin de ne pas me répéter, je ne reviendrai pas sur la documentation , car elle est très courte (l'ensemble du cadre est de 13 directives et 6 propriétés magiques) et sera bientôt disponible en russe (au moment de la rédaction, la traduction est sous l'approbation du créateur, mais c'est déjà peut être lu dans ma fourchette ).


Si vous êtes intéressé et / ou ne connaissez pas Vue, je le recommande vivement. Pour ceux qui connaissent bien Vue, une brève description des principales différences:


  • Au lieu de cela, nous v-utilisons x-, c'est-à-dire non v-model, mais x-model; non v-bind, mais x-bindpourquoi? C'est tes devoirs :)
  • x-if x-for template. Virtual DOM.
  • {{}} . x-text x-html, Vue.

.


, . . - ? – . – , , . – " , " .. ..


, , .


HTML, CDN Alpine


<!DOCTYPE html>
<html lang="ru">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>To-Do  Alpine.js</title>
    <script
      src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.3.5/dist/alpine.min.js"
      defer
    ></script>
  </head>
  <body></body>
</html>

Alpine , . .


, ? . x-data.


<div x-data="{ name: '' }">
  <p>, <span x-text="name"></span></p>
</div>

<div> , . name <div> .


, to-do. :


<div
  x-data="{ todos: [{id: 1, title: ' ', completed: false}, {id: 2, title: ' ', completed: false}, {id: 3, title: '  ', completed: false}, {id: 4, title: '  ', completed: false}] }"
>
  <h1>  :</h1>
  <ul>
    <template x-for="todo in todos" :key="todo.id">
      <li x-text="todo.title"></li>
    </template>
  </ul>
</div>

. , , CSS- .completed, x-bind:class ( {[ ]: []}). cursor: pointer li, .


<style>
  .completed {
    text-decoration: line-through;
  }

  li {
    cursor: pointer;
  }
</style>

<div
  x-data="{ todos: [{id: 1, title: ' ', completed: false}, {id: 2, title: ' ', completed: false}, {id: 3, title: '  ', completed: false}, {id: 4, title: '  ', completed: false}], toggleTodo: function(id) { var todo = this.todos.find((todo) => todo.id === id); todo.completed = !todo.completed; } }"
>
  <h1>  :</h1>
  <ul>
    <template x-for="todo in todos" :key="todo.id">
      <li
        x-text="todo.title"
        @click="toggleTodo(todo.id)"
        :class="{'completed': todo.completed}"
      ></li>
    </template>
  </ul>
</div>

, , . , x-data :


<div x-data="todos()">
  <h1>  :</h1>
  <ul>
    <template x-for="todo in todos" :key="todo.id">
      <li
        x-text="todo.title"
        @click="toggleTodo(todo.id)"
        :class="{'completed': todo.completed}"
      ></li>
    </template>
  </ul>
</div>

<script>
  function todos() {
    return {
      todos: [
        { id: 1, title: ' ', completed: false },
        { id: 2, title: ' ', completed: false },
        { id: 3, title: '  ', completed: false },
        { id: 4, title: '  ', completed: false },
      ],
      toggleTodo: function (id) {
        var todo = this.todos.find((todo) => todo.id === id);
        todo.completed = !todo.completed;
      },
    };
  }
</script>

… Vue.


input :


<div x-data="todos()">
  <!-- ... -->
  <div>
    <h4>  :</h4>
    <input type="text" x-model="inputValue" />
    <button @click="addTodo()"></button>
  </div>
</div>

<script>
  function todos() {
    return {
      // ...
      inputValue: '',
      addTodo: function () {
        if (!this.inputValue) {
          return;
        }

        this.todos.push({
          id: Date.now(),
          title: this.inputValue,
          completed: false,
        });
        this.inputValue = '';
      },
    };
  }
</script>

push() , Alpine , - .


– . <li> span: , – .


<ul>
  <template x-for="todo in todos" :key="todo.id">
    <li @click="toggleTodo(todo.id)" :class="{'completed': todo.completed}">
      <span x-text="todo.title"></span>
      <span @click="deleteTodo(todo.id)">&times;</span>
    </li>
  </template>
</ul>

<script>
  function todos() {
    return {
      // ...
      deleteTodo: function (id) {
        this.todos = this.todos.filter((todo) => todo.id !== id);
      },
    };
  }
</script>

.


, , , REST API. , JSON Placeholder. x-init.


<div x-data="todos()" x-init="fetchTodos()">
  <!-- ... -->
</div>

<script>
  function todos() {
    return {
      // ...
      todos: [],
      fetchTodos: function () {
        fetch('https://jsonplaceholder.typicode.com/todos')
          .then((response) => response.json())
          .then((data) => {
            this.todos = data.slice(0, 10);
          });
      },
    };
  }
</script>

x-init DOM ( created Vue). – , ( mounted).
, ?_limit=10, query , , .


. Alpine.js. . , . , , .


sandbox. , , .


PS Pour les anglophones, je veux également conseiller un screencast "presque totalement gratuit" du créateur d'Alpine.js. Il est si bon que même un lien est dommage à partager. Eh bien alors . L'auteur y explique comment créer un tel cadre comme Alpine et que ce n'est pas du tout aussi difficile qu'il y paraît.

All Articles