
La version finale de Phoenix 1.7 est disponible ! Phoenix 1.7 contient un certain nombre de nouvelles fonctionnalités très attendues comme les routes vérifiées, le support de Tailwind, les générateurs d'authentification LiveView, les modèles HEEx unifiés, les flux LiveView pour des collections optimisées, et bien plus encore. Il s'agit d'une version rétrocompatible avec quelques dépréciations. La plupart des gens devraient être en mesure de mettre à jour juste en changeant quelques dépendances.
Note : Pour générer un nouveau projet 1.7, vous devrez installer le générateur phx.new de hex :
Code : | Sélectionner tout |
mix archive.install hex phx_new
Les routes vérifiées remplacent les router helpers par une approche basée sur les sigils (~p) et vérifiée à la compilation.
note : Les routes vérifiées utilisent les nouvelles fonctionnalités du compilateur Elixir 1.14. Phoenix supporte toujours les anciennes versions d'Elixir, mais vous devrez les mettre à jour pour profiter des nouvelles fonctionnalités de vérification à la compilation.
En pratique, cela signifie que là où vous utilisiez auparavant des fonctions autogénérées comme :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | # router get "/oauth/callbacks/:id", OAuthCallbackController, :new # usage MyRouter.Helpers.o_auth_callback_path(conn, :new, "github") # => "/oauth/callbacks/github" MyRouter.Helpers.o_auth_callback_url(conn, :new, "github") # => "http://localhost:4000/oauth/callbacks/github" |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | # router get "/oauth/callbacks/:id", OAuthCallbackController, :new # usage ~p"/oauth/callbacks/github" # => "/oauth/callbacks/github" url(~p"/oauth/callbacks/github") # => "http://localhost:4000/oauth/callbacks/github" |
Il y a aussi maintenant une correspondance 1:1 entre les routes que vous écrivez dans le routeur, et la façon dont vous les appelez avec ~p. Vous l'écrivez simplement comme si vous codiez des chaînes en dur partout dans votre application - sauf que vous n'avez pas les problèmes de maintenance qui viennent avec le codage en dur des chaînes. Nous pouvons obtenir le meilleur des deux mondes avec la facilité d'utilisation et de maintenance parce que ~p est une vérification à la compilation des routes dans votre routeur.
Par exemple, imaginons que nous fassions une faute de frappe sur une route :
Code : | Sélectionner tout |
<.link href={~p"/userz/profile"}>Profile</.link>
Code : | Sélectionner tout |
1 2 3 | warning: no route path for AppWeb.Router matches "/postz/#{post}" lib/app_web/live/post_live.ex:100: AppWeb.PostLive.render/1 |
Code : | Sélectionner tout |
~p"/posts/#{post.id}"
Les chaînes de requête sont également prises en charge dans les itinéraires vérifiés, soit sous la forme traditionnelle d'une chaîne de requête :
Code : | Sélectionner tout |
~p"/posts?page=#{page}"
Code : | Sélectionner tout |
1 2 3 | params = %{page: 1, direction: "asc"} ~p"/posts?#{params}" |
Une fois que vous aurez essayé cette nouvelle fonctionnalité, vous ne pourrez plus revenir aux router helpers. Les nouveaux générateurs phx.gen.html|live|json|auth utilisent des routes vérifiées.
Générateurs Tailwind basés sur des composants
Phoenix 1.7 est livré avec TailwindCSS par défaut, sans dépendance avec nodejs sur le système. TailwindCSS est le meilleur moyen que j'ai trouvé pour styliser les interfaces en 20 ans de développement web. Son approche axée sur l'utilité est bien plus facile à maintenir et plus productive que n'importe quel système ou framework CSS que j'ai utilisé. Son approche colocalisée s'aligne parfaitement avec le composant de fonction et le paysage LiveView.
L'équipe de Tailwind a également généreusement conçu la nouvelle page d'accueil du projet, les pages CRUD et les pages du système d'authentification pour les nouveaux projets, vous donnant un point de départ de première classe et poli pour la construction de vos applications.
Un nouveau projet phx.new contiendra un module CoreComponents, abritant un ensemble de composants d'interface utilisateur tels que des tables, des fenêtres modales, des formulaires et des listes de données. La suite de générateurs Phoenix (phx.gen.html|live|json|auth) utilise les composants de base. Cela présente un certain nombre d'avantages intéressants.
Tout d'abord, vous pouvez personnaliser les composants de base de l'interface utilisateur en fonction de vos besoins, de vos conceptions et de vos goûts. Si vous souhaitez utiliser Bulma ou Bootstrap au lieu de Tailwind, pas de problème ! Remplacez simplement les définitions de fonctions dans core_components.ex par vos implémentations spécifiques au framework/UI et les générateurs continuent à fournir un excellent point de départ pour de nouvelles fonctionnalités, que vous soyez un débutant ou un expert chevronné construisant des fonctionnalités de produit sur mesure.
En pratique, les générateurs vous donnent des modèles qui utilisent vos composants de base, qui ressemblent à ceci :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <.header> New Post <:subtitle>Use this form to manage post records in your database.</:subtitle> </.header> <.simple_form for={@form} action={~p"/posts"}> <input field={@form[:title]} type="text" label="Title" /> <input field={@form[:views]} type="number" label="Views" /> <:actions> <.button>Save Post</.button> </:actions> </.simple_form> <.back navigate={~p"/posts"}>Back to posts></.back> |
Composants de fonction unifiés pour les contrôleurs et les LiveViews
Les composants de fonction fournis par HEEx, avec des affectations et des emplacements déclaratifs, constituent un changement radical dans la manière dont nous écrivons du HTML dans les projets Phoenix. Les composants de fonction fournissent des blocs de construction de l'interface utilisateur, permettant aux fonctionnalités d'être encapsulées et mieux étendues par rapport à l'approche précédente des modèles dans Phoenix.View. Vous bénéficiez d'une manière plus naturelle d'écrire des balises dynamiques, d'une interface utilisateur réutilisable qui peut être étendue par l'appelant, et de fonctions de compilation qui font de l'écriture d'applications HTML une expérience de premier ordre.
Les composants de fonction apportent une nouvelle façon d'écrire des applications HTML dans Phoenix, avec de nouveaux ensembles de conventions. En outre, les utilisateurs ont eu du mal à combiner les fonctionnalités Phoenix.View basées sur les contrôleurs avec les fonctionnalités Phoenix.LiveView dans leurs applications. Les utilisateurs se sont retrouvés à écrire render("table", user : user) dans des modèles basés sur des contrôleurs, tandis que leurs LiveViews utilisaient les nouvelles fonctionnalités <.table rows={@users}>. Il n'existait pas de moyen efficace de partager les approches dans une application.
Pour ces raisons, l'équipe de Phoenix a unifié les approches de rendu HTML, que ce soit à partir d'une requête de contrôleur ou d'une LiveView. Ce changement nous a également permis de revoir les conventions et de nous aligner sur l'approche LiveView qui consiste à regrouper les modèles et le code de l'application.
Les nouvelles applications (et les générateurs phx) suppriment Phoenix.View en tant que dépendance en faveur d'une nouvelle dépendance Phoenix.Template, qui utilise des composants de fonction comme base pour tous les rendus dans le framework.
Vos contrôleurs restent les mêmes :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 | defmodule AppWeb.UserController do use MyAppWeb, :controller def index(conn, _params) do users = ... render(conn, :index, users: users) end end |
Tout le rendu HTML est alors basé sur des composants de fonction, qui peuvent être écrits directement dans un module, ou intégrés à partir d'un fichier externe avec la nouvelle macro embed_templates fournie par Phoenix.Component. Votre module PageHTML dans une nouvelle application ressemble à ceci :
Code : | Sélectionner tout |
1 2 3 4 5 | defmodule AppWeb.PageHTML do use AppWeb, :html embed_templates "page_html/*" end |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | lib/app_wb ├── controllers │ ├── page_controller.ex │ ├── page_html.ex │ ├── error_html.ex │ ├── error_json.ex │ └── page_html │ └── home.html.heex ├── live │ ├── home_live.ex ├── components │ ├── core_components.ex │ ├── layouts.ex │ └── layouts │ ├── app.html.heex │ └── root.html.heex ├── endpoint.ex └── router.ex |
En outre, nous avons placé les modules de vue à côté de leurs fichiers de contrôle. Cela présente les mêmes avantages que la colocalisation LiveView : les fichiers fortement couplés vivent ensemble. Les fichiers qui doivent changer ensemble vivent désormais ensemble, qu'il s'agisse d'écrire des fonctionnalités LiveView ou des fonctionnalités de contrôleur.
Ces changements avaient pour but d'améliorer l'écriture des applications HTML, mais ils ont également simplifié le rendu d'autres formats, comme JSON. Par exemple, les modules de vue basés sur JSON suivent les mêmes conventions - Phoenix cherchera d'abord une fonction index/1 lors du rendu du modèle d'index, avant d'essayer render/2. Cela nous a permis de simplifier le rendu JSON en général et de supprimer des concepts tels que Phoenix.View.render_one|render_many.
Par exemple, voici une vue JSON générée par phx.gen.json :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | defmodule AppWeb.PostJSON do alias AppWeb.Blog.Post @doc """ Renders a list of posts. """ def index(%{posts: posts}) do %{data: for(post <- posts, do: data(post))} end @doc """ Renders a single post. """ def show(%{post: post}) do %{data: data(post)} end defp data(%Post{} = post) do %{ id: post.id, title: post.title } end end |
Ces fonctionnalités fournissent un modèle de rendu unifié pour les applications qui vont de l'avant avec une manière nouvelle et améliorée d'écrire des interfaces utilisateur, mais elles s'écartent des pratiques précédentes. La plupart des grandes applications établies sont probablement mieux servies en continuant à dépendre de Phoenix.View.
Streams LiveView
LiveView comprend désormais une interface de flux permettant de gérer de grandes collections dans l'interface utilisateur sans avoir à stocker les collections en mémoire sur le serveur. Avec quelques appels de fonction, vous pouvez insérer de nouveaux éléments dans l'interface utilisateur, les ajouter ou les ajouter dynamiquement, ou les réorganiser sans les recharger sur le serveur.
Le générateur CRUD phx.gen.live live de Phoenix 1.7 utilise des flux pour gérer votre liste d'éléments. Cela permet la saisie de données, les mises à jour et les suppressions sans jamais avoir besoin de récupérer la liste des éléments après le chargement initial. Voyons comment.
Le module PostLive.Index suivant est généré lorsque vous exécutez mix phx.gen.live Blog Post posts title views:integer
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | defmodule DemoWeb.PostLive.Index do use DemoWeb, :live_view alias Demo.Blog alias Demo.Blog.Post @impl true def mount(_params, _session, socket) do {:ok, stream(socket, :posts, Blog.list_posts())} end ... end |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <.table id="posts" rows={@streams.posts} row_click={fn {_id, post} -> JS.navigate(~p"/posts/#{post}") end} > <:col :let={{_id, post}} label="Title"><%= post.title %></:col> <:col :let={{_id, post}} label="Views"><%= post.views %></:col> <:action :let={{_id, post}}> <div class="sr-only"> <.link navigate={~p"/posts/#{post}"}>Show</.link> </div> <.link patch={~p"/posts/#{post}/edit"}>Edit</.link> </:action> < |
La fin de cet article est réservée aux abonnés. Soutenez le Club Developpez.com en prenant un abonnement pour que nous puissions continuer à vous proposer des publications.