Cómo usar Alpine.js con Rails y Turbo

Alpine.js es una de mis bibliotecas JavaScript favoritas. Es simple, rápida y fácil de integrar sin escribir demasiado código JavaScript.

Para aplicaciones Ruby on Rails donde haré la mayor parte del renderizado del lado del servidor, como a través de Turbo, y donde no quiero usar React o Vue.js (ni siquiera Stimulus), Alpine.js ofrece la cantidad justa de JavaScript.

En este tutorial, veremos cómo usar Alpine.js con tu aplicación Rails, y cómo agregar los siguientes elementos de UI:

  • Mensajes flash (desaparecen automáticamente)
  • Modal

El código de demostración para este tutorial se encuentra en https://github.com/Code-With-Rails/alpinejs-demo.

Instalación de Alpine.js con Rails

Para nuestra aplicación base, usaremos Rails 7 que soporta import maps.

bin/rails new rails-alpinejs-demo
cd rails-alpinejs-demo

bin/rails importmap:install
bin/importmap pin alpinejs
bin/importmap pin alpine-turbo-drive-adapter

Agrega a tu application.js:

import '@hotwired/turbo-rails'
import 'alpine-turbo-drive-adapter'
import Alpine from 'alpinejs'

window.Alpine = Alpine
Alpine.start()

Un Ejemplo Rápido

<div x-data="{ open: false }">
  <button x-on:click="open = ! open">Alternar</button>
  <span x-show="open">¡Estoy aquí!</span>
</div>

La belleza de Alpine.js es que no hay código JavaScript adicional que escribir en otro lugar. Puedes declarar cómo los elementos responden a eventos iniciados por el usuario y alterar el estado de los datos en consecuencia.

Construyendo Mensajes Flash

Los mensajes flash con Alpine.js pueden desaparecer automáticamente usando x-init y setTimeout:

<%# app/views/layouts/_flash_message.html.erb %>
<%= turbo_frame_tag 'flash' do %>
  <% unless flash[:notice].blank? %>
    <div x-init="() => { flashShown = true; setTimeout(() => { flashShown = false }, 4000) };">
      <%= flash[:notice] %>
    </div>
  <% end %>
<% end %>

Construyendo un Modal

Para modales, combina Turbo Streams con transiciones de Alpine.js:

<div x-init="$nextTick(() => { isModalOpen = true })"
     x-show="isModalOpen"
     x-transition:enter="ease-out duration-300"
     x-transition:enter-start="opacity-0"
     x-transition:enter-end="opacity-100">
  <!-- Contenido del modal -->
</div>

Conclusión

Alpine.js me permite enfocarme en el renderizado del lado del servidor y minimizar la cantidad de código JavaScript que necesito. Cuando uso Alpine.js y trabajo dentro de lo que está diseñado (pequeñas interacciones ligeras que requieren JS), mi aplicación y su base de código se sienten más ligeras.

Te animo a revisar el repositorio de la aplicación de demostración en https://github.com/Code-With-Rails/alpinejs-demo y verlo por ti mismo.

Ultima actualizacion 27 de febrero de 2024