Vue : construire une application web (école d'ingénieur) · Chapitre 12 · Exercice de TD
La recherche au serveur
Projet : la Librairie en application Vue · niveau 3 (difficile)
Énoncé
Avec un très grand catalogue, la recherche doit être faite par le serveur (GET /api/livres?q=…). Écrire un composant de recherche qui interroge le serveur, sans envoyer une requête à chaque touche : seulement quand l'utilisateur a cessé de taper depuis 300 ms. Combien de requêtes partent quand on tape « java » à raison d'une touche toutes les 100 ms ? Le vérifier avec un test à temps simulé.
Corrigé
On combine le composable useDifferee du chapitre 11 et useFetch, dont l'adresse est une fonction de la recherche différée :
<script setup>
import { ref } from "vue";
import { useFetch } from "@/composables/useFetch.js";
import { useDifferee } from "./useDifferee.js";
const saisie = ref("");
// Le serveur ne reçoit la recherche qu'après 300 ms sans frappe.
const recherche = useDifferee(saisie, 300);
const { donnees: livres, chargement } = useFetch(
() => `/api/livres?q=${encodeURIComponent(recherche.value)}`,
);
</script>
<template>
<p>
<label for="q">Rechercher</label>
<input
id="q"
v-model="saisie"
type="search"
>
</p>
<ul :aria-busy="chargement">
<li
v-for="livre in livres ?? []"
:key="livre.isbn"
>
{{ livre.titre }}
</li>
</ul>
</template>
test("quatre frappes rapides, une seule requête de recherche", async () => {
vi.useFakeTimers();
const fetch = vi.fn(async () => ({ ok: true, status: 200, json: async () => [] }));
vi.stubGlobal("fetch", fetch);
const page = mount(RechercheServeur);
for (const texte of ["j", "ja", "jav", "java"]) {
await page.find("#q").setValue(texte);
vi.advanceTimersByTime(100); // 100 ms entre deux touches
}
vi.advanceTimersByTime(300); // l'utilisateur s'arrête
await flushPromises();
console.info(fetch.mock.calls.map(([url]) => url));
expect(fetch).toHaveBeenCalledTimes(2);
});
[ '/api/livres?q=', '/api/livres?q=java' ]
Deux requêtes : celle du premier affichage (recherche vide), puis une seule pour « java », 300 ms après la dernière touche. Les trois états intermédiaires (« j », « ja », « jav ») n'ont jamais quitté le navigateur. Si une ancienne requête revenait après une plus récente, useFetch l'aurait de toute façon annulée.
100 % gratuit
La suite du chapitre est sur Adloun
- 9 autres exercices corrigés dans ce chapitre
- Les 2 QCM du chapitre, le premier sans compte
- Le tuteur, qui guide pas à pas sans donner la réponse
Sans compte : le cours et le premier QCM. Exercices et tuteur : inscription gratuite en 30 secondes, sans carte bancaire.