Alpine.js em um exemplo concreto

Você já deve ter ouvido falar do Alpine.js. Caso contrário, esse é "Vue.js no mínimo". "Angular 1 para a geração do milênio". Chame como quiser, a principal coisa que você entende.


Por que precisamos de outra estrutura? Bem, Alpine se encaixa bem em seu nicho. De fato, é uma alternativa para grandes estruturas para sites onde essas grandes estruturas não são necessárias. Por exemplo, eu, um desenvolvedor web da moda, foi contratado para escrever um site de várias páginas. Eu preciso fazer um formulário elementar e qualquer outro interativo. O que eu farei? Vou usar o jQuery - amigos não entendem, na escrita JS pura, tudo também não é comum. Além disso, eu já sei as reações, ângulos e visão, sei o que é uma abordagem orientada a dados. Como agora armazeno dados antes de enviar em HTML?


Aqui o Alpine.js vem em socorro. Obviamente, você pode estragar o Vue ou React. Mas Reagir sem JSX, ninguém no seu perfeito juízo escreveria, e o Vue compactado via CDN pesa 34 kB (contra 8,1 kB para a Alpine). Acontece que a escolha recai sobre a Alpine.


Recentemente, aqui no Habré, já havia artigos de familiarização sobre o Alpine.js . Além do fato de o site ter cortado referências à tag template em todos os lugares, os artigos acabaram sendo muito bons.


Para não me repetir, não recontarei a documentação , pois é muito curta (toda a estrutura é composta de 13 diretivas e 6 propriedades mágicas) e em breve estará disponível em russo (no momento em que escrevo, a tradução está sob a aprovação do criador, mas já está pode ser lido no meu garfo ).


Se você está interessado e / ou não está familiarizado com o Vue, eu o recomendo. Para aqueles que estão familiarizados com o Vue, uma breve descrição das principais diferenças:


  • Em vez disso, v-usamos x-, ou seja, não v-model, mas x-model; não v-bind, mas x-bindpor que? Este é o seu dever de casa :)
  • 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 Para falantes de inglês, também quero aconselhar um screencast "quase totalmente gratuito" do criador do Alpine.js. Ele é tão bom que até um link é uma pena compartilhar. Bem então . Nele, o autor fala sobre como criar uma estrutura como a Alpine, e que não é tão difícil quanto parece.

All Articles