Article original : How to Build Web Apps with Nuxt and Laravel
Le framework Laravel est l'une des technologies les plus utilisées dans l'écosystème du développement web. Il est relativement simple et facile à utiliser pour créer des sites web.
Laravel est construit sur PHP, un langage de programmation web populaire utilisé dans plus de 75 % des sites web sur le web. Savoir utiliser un framework comme Laravel peut donc vous aider à devenir un développeur recherché – et cela rend également la création de sites web et d'applications plus fluide.
Nuxt est un framework Vue.js utilisé pour créer des applications web riches et interactives. Il vous permet de choisir entre différents modes de rendu en fonction des exigences de l'application que vous souhaitez créer. Vous pouvez choisir entre la création d'une application entièrement rendue côté serveur ou côté client. Nuxt offre également un mélange des deux modes de rendu, rendant les applications beaucoup plus puissantes, efficaces et interactives.
Dans cet article, vous apprendrez à créer des applications full-stack en utilisant Nuxt et Laravel en construisant une application de bibliothèque de livres. L'application comprendra une API de bibliothèque que nous créerons en utilisant Laravel et un frontend utilisant Nuxt.
Nous parlerons de :
- Installation et configuration de Laravel
- Création de modèles de base de données
- Migrations
- Contrôleurs
- Tests d'API
- Validations de formulaires
- Récupération de données dans Nuxt
Et plus encore. Préparez-vous, et plongeons.
Table des matières :
- Prérequis
- Comment installer Laravel sur votre machine
- Comment intégrer l'API Laravel dans le frontend
- Conclusion
- Ressources
Prérequis
- PHP et Composer sont installés sur votre machine locale.
- Node.js est installé sur votre machine locale.
- yarn ou npm installé sur votre machine locale (npm est préinstallé avec Node).
- Un éditeur de texte installé, comme VSCode.
- Connaissances de base en HTML, CSS, JavaScript et terminal.
- Connaissances de base en PHP, Vue.js et TypeScript.
Comment installer Laravel sur votre machine
Pour commencer l'installation de Laravel, ouvrez votre terminal et initialisez un nouveau projet Laravel avec la commande suivante :
composer create-project laravel/laravel library-api && cd library-api && code .
Cette commande crée un nouveau projet Laravel dans votre répertoire, se déplace dedans avec cd, et ouvre VSCode avec la commande code .. (Si vous utilisez un autre éditeur, vous pouvez supprimer cette commande et ouvrir le répertoire manuellement).
Pour tester votre serveur Laravel et vous assurer que tout fonctionne, testons le serveur en utilisant la commande php artisan serve dans le terminal. Cela devrait rendre votre API disponible sur le port 8000 et accessible dans votre navigateur.
Application de démarrage Laravel
Comment construire l'API de la bibliothèque de livres
Nous allons créer un endpoint CRUD simple pour notre bibliothèque de livres, c'est-à-dire que l'API doit être capable de réaliser les actions suivantes :
- Créer de nouvelles entrées de livres
- Obtenir une liste de toutes les entrées de livres dans la base de données
- Modifier les entrées de livres ajoutées précédemment
- Supprimer les entrées de livres de la base de données
Configuration de la base de données
Laravel propose une variété de bases de données que vous pouvez utiliser pendant le développement. Par défaut, il crée automatiquement une configuration pour MySQL. Mais pour simplifier, nous utiliserons une base de données SQLite dans ce tutoriel.
Ouvrez le fichier .env dans votre répertoire racine, changez la valeur DB_CONNECTION de mysql à sqlite, et commentez les autres configurations de la base de données comme vous pouvez le voir ci-dessous :
Variables d'environnement (disponibles dans le fichier .env)
Laravel crée automatiquement la base de données SQLite lorsque la commande de migration est exécutée. Nous le ferons dans un instant après avoir créé nos modèles de base de données.
Création du modèle de livre
Lorsque vous construisez des API backend, un modèle sert de modèle utilisé pour configurer vos tables de base de données. Il contient des instructions de haut niveau sur la manière dont les tables et les colonnes doivent être créées.
Dans Laravel, vous pouvez utiliser la commande suivante pour créer un modèle Book :
php artisan make:model Book -m
Cela crée votre modèle Book dans le répertoire app/models et crée également un nouveau fichier de migration pour vous dans le répertoire database/migrations.
Accédez au répertoire des migrations et ouvrez le fichier de migration nouvellement créé. Il devrait être au format current_date_create_books_table.php comme vous pouvez le voir ci-dessous :
Migrations par défaut
Modifiez la fonction up et ajoutez le contenu suivant :
$table->string('title');
$table->string('author');
$table->string('isbn');
$table->date('published_date');
$table->text('cover_image')->nullable();
$table->foreignIdFor(User::class);
Votre fichier de migration devrait maintenant ressembler à ceci :
Migrations mises à jour
En résumé, vous avez ajouté de nouveaux champs à créer pour les tables de livres. Title, author et isbn ont tous un type de données string, tandis que published_date et cover_image ont des types de données date et text, respectivement.
Vous avez également rendu cover_image nullable, c'est-à-dire que le champ peut être omis lors de la création d'une nouvelle entrée de livre.
Enfin, vous avez importé la classe User et en avez fait une clé étrangère de votre table Book, créant une relation plusieurs-à-un avec la table User.
Maintenant, créons vos tables en exécutant le fichier de migration avec la commande suivante :
php artisan migrate
Vous devriez obtenir une invite dans le terminal vous demandant si vous souhaitez créer votre base de données SQLite avant les migrations. Sélectionnez oui et appuyez sur Entrée pour procéder aux migrations.
Une fois la migration exécutée avec succès, accédez au modèle Book et collez le code suivant :
/**
* Les attributs qui sont assignables en masse.
*
* @var array<int, string>
*/
protected $fillable = [
'user_id',
'title',
'author',
'isbn',
'published_date',
'cover_image'
];
Cela permettra l'assignation en masse lors du passage de données dans le modèle (passage des données en bloc au lieu de manière individuelle). Votre modèle Book devrait maintenant ressembler à ceci :
Modèle Book mis à jour
Création du contrôleur de livre
Le contrôleur est responsable du logement de la logique métier pour toute API créée. La logique d'implémentation pour la manière dont nous voulons effectuer des opérations CRUD avec l'API de la bibliothèque résidera ici.
Laravel fournit également une commande pour faciliter cela pour les développeurs. Collez la commande suivante dans votre terminal pour créer notre contrôleur de livre :
php artisan make:controller BookController
Cela devrait être accessible à app\Http\Controllers\BookController.php. Remplacez le contenu de votre classe BookController par l'extrait de code suivant :
<?php
namespace App\Http\Controllers;
use App\Models\Book;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
class BookController extends Controller
{
public function store(Request $request)
{
$data = $request->validate([
'title' => 'required|string',
'author' => 'required|string',
'isbn' => 'required|string|unique:books',
'published_date' => 'required|string',
'cover_image' => 'nullable|image|max:2048',
]);
try {
$published_date = Carbon::parse($data['published_date'])->toDateString();
$data['published_date'] = $published_date;
$data['user_id'] = 1; // En supposant que l'id de l'utilisateur est 1
} catch (\Exception $e) {
return response()->json(['Error' => 'Bad Request'], 400);
}
$book = new Book($data);
if ($request->hasFile('cover_image')) {
$coverImage = $request->file('cover_image');
$coverImageName = time() . '.' . $coverImage->getClientOriginalExtension();
$coverImage->move(public_path('images'), $coverImageName);
$book->cover_image = $coverImageName;
}
$book->save();
return response()->json(['message' => 'Book added successfully'], 201);
}
public function index()
{
$books = Book::all();
return response()->json(['books' => $books], 200);
}
public function update(Request $request, $id)
{
$book = Book::findOrFail($id);
$data = $request->all();
try {
$published_date = Carbon::parse($data['published_date'])->toDateString();
$data['published_date'] = $published_date;
$data['user_id'] = $book->user_id;
} catch (\Throwable $th) {
Log::error('Error ', $th);
return response()->json(['Error' => 'Bad Request'], 400);
}
$book->update($data);
if ($request->hasFile('cover_image')) {
// Supprimer l'ancienne image de couverture si elle existe
if ($book->cover_image) {
Storage::delete('public/images/' . $book->cover_image);
}
$coverImage = $request->file('cover_image');
$coverImageName = time() . '.' . $coverImage->getClientOriginalExtension();
$coverImage->storeAs('public/images', $coverImageName);
$book->cover_image = $coverImageName;
$book->save();
}
return response()->json(['message' => 'Book updated successfully'], 200);
}
public function destroy($id)
{
$book = Book::findOrFail($id);
// Supprimer l'image de couverture si elle existe
if ($book->cover_image) {
Storage::delete('public/images/' . $book->cover_image);
}
$book->delete();
return response()->json(['message' => 'Book deleted successfully'], 200);
}
}
Définition des routes API
Le routage est l'une des parties les plus importantes de la création d'une API. Les routes servent de points d'accès par lesquels les développeurs, les clients ou tout autre service peuvent accéder à une API.
Le routeur Laravel vous permet d'enregistrer des routes qui correspondent à n'importe quel verbe HTTP demandé.
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
Accédez au fichier routes/api.php et créez les routes suivantes pour votre API :
Route::post('/books', [BookController::class, 'store']);
Route::get('/books', [BookController::class, 'index']);
Route::put('/books/{id}', [BookController::class, 'update']);
Route::delete('/books/{id}', [BookController::class, 'destroy']);
Test de l'API
Maintenant, il est temps de tester votre API et de vous assurer que tous vos endpoints sont accessibles et fonctionnent comme prévu.
Exécutez le serveur Laravel avec la commande suivante :
php artisan serve
Vous pouvez tester l'API en utilisant n'importe quel client API de votre choix. Nous avons plusieurs options populaires parmi lesquelles choisir – Postman, Insomnia, Thunder Client, etc. J'utiliserai Thunder Client ici.
Nous testerons toutes les opérations CRUD dans votre client API en confirmant si tous vos objectifs pour votre API sont atteints.
Création d'un nouveau livre
Endpoint de création de livre
Obtention d'une liste de livres
Endpoint d'obtention de livres
Édition d'un livre
Endpoint d'édition de livre
Comment construire le frontend Nuxt
La configuration d'une nouvelle application Nuxt est aussi simple que d'exécuter la commande suivante :
npx nuxi@latest init nuxt-library-frontend
Ouvrez le projet nouvellement créé une fois que vous avez terminé l'installation de toutes les dépendances et démarrez le serveur de développement avec cette commande :
npm run dev
Votre application Nuxt devrait maintenant être accessible sur le port 3000 :
Page de démarrage Nuxt
Voici à quoi votre frontend devrait ressembler à la fin du tutoriel :
Exemple de notre application terminée
J'ai créé un code de base pour aider à la configuration du frontend Nuxt. Cela nous permettra de nous concentrer sur la logique d'implémentation pour consommer l'API Laravel plutôt que de passer du temps à configurer les choses et à les styliser.
Pour information, j'ai créé les composants d'interface utilisateur pour l'application en utilisant shadcn-vue. Il s'agit d'une collection incroyable de composants d'interface utilisateur accessibles et réutilisables que vous pouvez personnaliser selon vos goûts. Consultez les étapes d'installation pour plus de détails sur la facilité de configuration pour l'application Nuxt.
Il inclut également une installation de la bibliothèque d'utilitaires Tailwind CSS que nous utiliserons pour le style dans ce tutoriel.
Clonez la configuration de base depuis le dépôt GitHub ici pour que nous puissions commencer.
Accédez à pages/index.vue et remplacez le contenu de la page d'accueil par ceci :
<template>
<main class="bg-white p-10 min-h-screen">
<div class="max-w-4xl mx-auto">
<header class="flex justify-between items-center mb-20">
<h1 class="font-semibold text-4xl">My Library</h1>
<Button>Add New Book</Button>
</header>
<div v-if="isLoading">
<p class="italic text-2xl font-medium text-center">Loading...</p>
</div>
<div class="mt-8">
<div class="flex flex-col gap-8">
<div class="flex gap-4" v-for="book in books">
<div
v-if="book.cover_image"
class="rounded-lg w-32 h-44 flex items-center justify-center"
>
<NuxtImg
:src="`${API_BASE_URL}/images/${book.cover_image}`"
:alt="book.title"
class="w-full h-auto"
/>
</div>
<div v-else class="bg-slate-300 rounded-lg w-32 h-44"></div>
<div class="flex items-center justify-between flex-1">
<div>
<h3 class="font-medium text-xl mb-4">{{ book.title }}</h3>
<p class="mb-2">
<span>by:</span>
<span class="italic"> {{ book.author }} </span>
</p>
<p>
<span>Published:</span>
{{ book.published_date }}
</p>
</div>
<div class="actions flex gap-4">
<Button>Edit</Button>
<Button variant="destructive"> Delete </Button>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
</template>
<script lang="ts" setup>
import { API_BASE_URL } from "@/utils/constants";
import type { BookProps } from "@/utils/types";
const isLoading = ref(false);
const books = ref<BookProps[]>([]);
</script>
Nous devons créer un nouveau dossier appelé utils dans votre projet racine qui contiendra deux fichiers : constants.ts et types.ts. Collez l'extrait de code suivant dans votre fichier constants.ts :
export const API_BASE_URL = "http://localhost:8000";
Et le suivant dans votre types.ts :
export interface BookProps {
id?: number;
title: string;
author: string;
isbn: string;
published_date: string;
cover_image?: string;
user_id?: number;
created_at?: string;
updated_at?: string;
}
Enregistrez le fichier pages/index.vue. Vous devriez pouvoir voir ce résultat dans votre navigateur :
Échafaudage du frontend de la bibliothèque avec Nuxt
Maintenant, nous devons créer un tiroir latéral et une boîte de dialogue pour ajouter de nouveaux livres et supprimer les livres ajoutés de la base de données, respectivement.
Créez un nouveau fichier appelé BookDrawer.vue dans la racine des composants et ajoutez le code suivant :
<script setup lang="ts">
import type { BookProps } from "@/utils/types";
type PickedProps = "title" | "author" | "isbn" | "published_date";
interface CustomBookProps extends Pick<BookProps, PickedProps> {
cover_image?: string;
}
const props = defineProps<{ open: boolean; book?: BookProps }>();
const emit = defineEmits(["update:open", "refresh-data"]);
const isSubmitting = ref(false);
let form = reactive<CustomBookProps>({
title: "",
author: "",
isbn: "",
published_date: "",
cover_image: undefined,
});
const onFileChange = async (e: any) => {
form.cover_image = e.target.files[0];
};
const onSubmit = async () => {};
const closeDrawer = (openState: boolean) => emit("update:open", openState);
</script>
<template>
<Sheet :open="open" @update:open="closeDrawer">
<SheetContent class="w-full bg-white">
<SheetHeader>
<SheetTitle>
<template v-if="book"> Edit Book </template>
<template v-else>Add New Book</template>
</SheetTitle>
<SheetDescription>
Make changes to your profile here. Click save when you're done.
</SheetDescription>
</SheetHeader>
<div class="grid gap-4 py-4">
<div class="grid grid-cols-4 items-center gap-4">
<Label for="bookTitle" class="text-right"> Book Title </Label>
<Input
v-model:model-value="form.title"
type="text"
id="bookTitle"
class="col-span-3"
required
/>
</div>
<div class="grid grid-cols-4 items-center gap-4">
<Label for="author" class="text-right"> Author </Label>
<Input
v-model:model-value="form.author"
type="text"
id="author"
class="col-span-3"
required
/>
</div>
<div class="grid grid-cols-4 items-center gap-4">
<Label for="isbn" class="text-right"> ISBN </Label>
<Input
v-model:model-value="form.isbn"
type="text"
id="isbn"
class="col-span-3"
required
/>
</div>
<div class="grid grid-cols-4 items-center gap-4">
<Label for="published_date" class="text-right">
Published Date
</Label>
<Input
v-model:model-value="form.published_date"
type="date"
id="published_date"
class="col-span-3"
required
/>
</div>
<div class="grid grid-cols-4 items-center gap-4">
<Label for="cover_image" class="text-right"> Book Cover </Label>
<Input
type="file"
@change="onFileChange"
id="cover_image"
class="col-span-3"
required
/>
</div>
</div>
<SheetFooter>
<Button type="submit" @click="onSubmit">
<template v-if="isSubmitting">Saving...</template>
<template v-else> Save changes </template>
</Button>
</SheetFooter>
</SheetContent>
</Sheet>
</template>
Créez un autre fichier appelé DeleteBookDrawer.vue et ajoutez le contenu de code suivant :
<script lang="ts" setup>
const emit = defineEmits(["refresh-data", "update:open"]);
const props = defineProps<{ open: boolean; book?: BookProps }>();
</script>
<template>
<AlertDialog
:open="open"
@update:open="(openState) => $emit('update:open', openState)"
>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
<AlertDialogDescription>
This action cannot be undone. This will permanently delete your book
and remove your data from the server.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel @click="$emit('update:open', false)"
>Cancel</AlertDialogCancel
>
<AlertDialogAction>Continue</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</template>
Importez les fichiers nouvellement créés dans votre page d'accueil comme vous pouvez le voir ci-dessous :
<template>
<main class="bg-white p-10 min-h-screen">
...
<BookDrawerDialog
v-if="isBookDrawerOpen"
:open="isBookDrawerOpen"
@update:open="(open: boolean) => isBookDrawerOpen = open"
:book="currentBook"
@refresh-data="fetchBooks"
/>
<DeleteBookDialog
v-if="isDeleteBookDialogOpen"
:open="isDeleteBookDialogOpen"
@update:open="(open: boolean) => isDeleteBookDialogOpen = open"
:book="currentBook"
@refresh-data="fetchBooks"
/>
</main>
</template>
Maintenant, nous devons créer un système pour ouvrir et fermer le tiroir et la boîte de dialogue, respectivement. Nous allons créer un ref pour suivre l'état ouvert/fermé pour les composants de tiroir et de boîte de dialogue dans votre page d'accueil. Collez le contenu de code suivant dans la section script pour activer cela :
<script lang="ts" setup>
...
const currentBook = ref<BookProps>();
const isBookDrawerOpen = ref(false);
const isDeleteBookDialogOpen = ref(false);
const toggleAddBookDrawer = () => {
isBookDrawerOpen.value = !isBookDrawerOpen.value;
};
const toggleEditBookDrawer = (book: BookProps) => {
currentBook.value = book;
isBookDrawerOpen.value = !isBookDrawerOpen.value;
};
const toggleDeleteDialog = (book: BookProps) => {
currentBook.value = book;
isDeleteBookDialogOpen.value = !isDeleteBookDialogOpen.value;
};
</script>
Mettez à jour les boutons Edit et Delete dans votre page d'accueil pour inclure le gestionnaire de bascule :
...
<div class="actions flex gap-4">
<Button @click="toggleEditBookDrawer(book)">Edit</Button>
<Button @click="toggleDeleteDialog(book)" variant="destructive">
Delete
</Button>
</div>
...
Incluez le toggleAddDrawer dans votre bouton Add Book également :
<Button @click="toggleAddBookDrawer">Add New Book</Button>
Enregistrez les modifications du fichier et visualisez dans votre navigateur. Vous devriez avoir le tiroir actif maintenant :
Tiroir Ajouter un nouveau livre
Ensuite, nous devons nous assurer que le EditDrawer et le Delete Dialog fonctionnent. Nous allons créer un tableau temporaire de données de livres fictifs pour tester cela afin que vous puissiez voir le résultat sur votre page. Mettez à jour la valeur de la référence books avec les données que vous avez ci-dessous (et n'oubliez pas de mettre à jour la valeur de la référence books à un tableau vide – c'est-à-dire books = ref<BookProps>([])) :
const books = ref<BookProps[]>([
{
title: "Atomic Habits",
author: "James Clear",
isbn: "XYEOUIUEHEJ2902",
published_date: "2020-09-01",
cover_image: "",
},
{
title: "The Power of Habits",
author: "Charles Duhigg",
isbn: "WIUIQUEWHSDBSD28",
published_date: "2012-02-28",
cover_image: "",
},
]);
Enregistrez les modifications et vérifiez le EditDrawer et le DeleteDialog en action :
Boîte de dialogue de suppression
EditDrawer
Comment intégrer l'API Laravel dans le frontend
Obtention de tous les livres de la bibliothèque
Jusqu'à présent, nous n'avons que l'interface utilisateur de notre frontend qui fonctionne, et les données affichées ne proviennent pas de l'API. Pour rendre l'application entièrement dynamique, vous devez faire une requête HTTP au serveur pour obtenir toutes les données dont vous avez besoin pour votre page.
Mettez à jour le corps de la fonction fetchBooks dans la page d'accueil avec le code suivant :
const fetchBooks = async () => {
try {
isLoading.value = true;
const response = await $fetch<{ books: BookProps[] }>(
`${API_BASE_URL}/api/books`
);
books.value = response.books.sort(
(a, b) =>
Number(new Date(b.created_at as string)) -
Number(new Date(a.created_at as string))
);
} catch (error) {
console.log(error);
} finally {
isLoading.value = false;
}
};
onMounted(() => {
fetchBooks();
});
En gros, vous appelez votre fonction fetchBooks lorsque la page est montée en utilisant l'un des hooks de cycle de vie disponibles dans Vue.js. Lorsque la fonction est appelée, elle exécute l'instruction que vous avez créée dans le corps :
- Définir l'état de chargement de l'application sur vrai.
- Faire une requête HTTP GET à l'endpoint des livres de votre API et définir la réponse à la référence des livres que vous avez créée précédemment.
- Lorsque la requête-réponse a été complétée, définir l'état de chargement de l'application sur faux pour indiquer à l'utilisateur que le processus a été complété.
Enregistrez les modifications, et vous devriez voir les résultats dans le navigateur :
Récupération de la liste des livres
Création d'un nouveau livre
Pour que la création de votre livre soit réussie, vous devez inclure la logique de création d'un livre dans votre BookDrawer. Ajoutez le code suivant dans le fichier BookDrawer.vue :
...
const isSubmitting = ref(false);
const addNewBook = async (data: any) => {
const response = await $fetch(`${API_BASE_URL}/api/books`, {
method: "POST",
body: data,
headers: {
Accept: "application/json",
},
});
return response;
};
const onSubmit = async () => {
try {
const formData = new FormData();
Object.keys(form).forEach((key) => {
// @ts-ignore
if (form[key]) {
formData.append(key, form[key as never]);
}
});
isSubmitting.value = true;
const data = await addNewBook(formData);
closeDrawer(false);
emit("refresh-data");
} catch (error) {
console.log(error);
} finally {
isSubmitting.value = false;
}
};
...
Similaire à l'implémentation pour récupérer vos livres, la seule différence ici est que vous faites une requête HTTP POST à la place. Vous utilisez cette méthode chaque fois que vous devez muter des données sur le serveur.
Création d'un nouveau livre
Édition d'un livre
Mettez à jour votre BookDrawer avec le code suivant pour permettre l'édition des livres qui ont été ajoutés :
<script setup lang="ts">
...
onMounted(() => {
if (props.book) {
form = props.book;
}
});
const editBook = async () => {
try {
isSubmitting.value = true;
const resp = await $fetch(`${API_BASE_URL}/api/books/${props?.book?.id}`, {
method: "PUT",
body: formData,
});
closeDrawer(false);
emit("refresh-data");
} catch (error) {
console.log(error);
} finally {
isSubmitting.value = false;
}
};
...
</script>
Mettez à jour le bouton de sauvegarde avec le gestionnaire de bascule également :
<Button
type="submit"
@click="() => (book?.id ? editBook() : onSubmit())"
>
<template v-if="isSubmitting">Saving...</template>
<template v-else> Save changes </template>
</Button>
Et voici le résultat :
Mise à jour d'un livre
Suppression d'un livre
Collez ce qui suit dans le fichier DeleteBookDialog.vue :
const refreshData = () => emit("refresh-data");
const closeDialog = () => emit("update:open", false);
const deleteBook = async () => {
await $fetch(`${API_BASE_URL}/api/books/${props?.book?.id}`, {
method: "DELETE",
});
closeDialog();
refreshData();
};
Cela fonctionne également bien :
Suppression d'un livre
Conclusion
Construire des applications web full-stack avec Laravel et Nuxt est une expérience très enrichissante, car vous pouvez profiter des avantages et des récompenses des deux mondes.
Puisque Laravel est un framework backend riche en fonctionnalités, il est livré avec de nombreux modules et packages que vous pouvez installer chaque fois qu'une fonctionnalité ou une implémentation doit être travaillée.
Et Nuxt, en tant que framework Vue, vous donne le superpouvoir de construire des applications monopages qui sont rapides, accessibles et réactives, offrant aux utilisateurs finaux une expérience agréable.
Dans ce tutoriel, nous avons vu comment construire des applications full-stack en utilisant Nuxt et le framework Laravel. J'espère que vous avez pu apprendre quelque chose de nouveau et que vous êtes enthousiaste à l'idée d'explorer cela plus avant. N'hésitez pas à me contacter si vous avez des questions ou des idées.
Le code complet du tutoriel peut être trouvé dans le dépôt GitHub ici.
Ressources
- Documentation Laravel
- Documentation Nuxt
- Shadcn-vue, composants d'interface utilisateur prêts à l'emploi qui peuvent être copiés-collés à tout moment
- Documentation Vue