Ajouter l'autocomplétion d'adresses à Vue
Un champ d'adresse qui propose des suggestions pendant la frappe est la centaine de lignes la plus rentable de la plupart des tunnels de commande, et ce que les gens ratent n'est pas l'appel d'API. C'est la limitation du débit, la longueur minimale de requête, et ce qui arrive quand la personne tape plus vite que le réseau ne répond.
Installation
npx @unmap/cli add geocodernpm i @unmap/vueSur Vue et Nuxt, la voie du registre passe par shadcn-vue : l'élément arrive donc comme un
répertoire avec un index.ts et s'appuie sur vos propres Combobox, Field et Input.
Le composant
<script setup lang="ts">
import { UnmapGeocoder } from "@/components/ui/geocoder";
const apiKey = import.meta.env.VITE_UNMAP_KEY as string;
</script>
<template>
<UnmapGeocoder :api-key="apiKey" placeholder="Adresse" :limit="5" />
</template><script setup lang="ts">
import { ref } from "vue";
import { useGeocoder } from "@unmap/vue";
const { autocomplete, results, loading } = useGeocoder({
key: import.meta.env.VITE_UNMAP_KEY as string,
});
const query = ref("");
</script>
<template>
<div>
<input v-model="query" placeholder="Adresse" @input="autocomplete(query, { limit: 5 })" />
<span v-if="loading">Recherche…</span>
<ul>
<li v-for="result in results" :key="result.id">{{ result.name }}</li>
</ul>
</div>
</template>Notez encore l'orthographe de la clé : le composant prend api-key, le composable prend key.
results et loading sont des refs : le template les déballe, et le code de script a besoin de
.value.
L'anti-rebond vous revient sur la voie du paquet
L'extrait ci-dessus se déclenche à chaque frappe, et chaque requête d'autocomplétion est un appel facturé. Taper une adresse de rue sans limitation fait vingt appels pour répondre à une seule question. Le composant copié applique un anti-rebond de 200 ms ; le composable non, volontairement.
<script setup lang="ts">
import { ref, watch } from "vue";
import { useGeocoder } from "@unmap/vue";
const { autocomplete, results } = useGeocoder({
key: import.meta.env.VITE_UNMAP_KEY as string,
});
const query = ref("");
let timer: ReturnType<typeof setTimeout> | undefined;
watch(query, (value) => {
clearTimeout(timer);
if (value.length < 3) return;
timer = setTimeout(() => void autocomplete(value, { limit: 5 }), 200);
});
</script>
<template>
<div>
<input v-model="query" placeholder="Adresse" />
<ul>
<li v-for="result in results" :key="result.id">{{ result.name }}</li>
</ul>
</div>
</template>Ce que ce n'est pas
Ceci propose des adresses issues d'un corpus canadien ouvert. Cela ne valide pas qu'une adresse est livrable, ne la corrige pas au format de Postes Canada et ne confirme pas qu'un numéro d'unité existe. S'il vous faut une vérification d'adresse certifiée pour du courrier, c'est un autre type de produit et unmap n'en est pas un.
Ce qu'il fait bien, c'est trouver le lieu que la personne a en tête, en anglais ou en français, avec les deux noms sur la même fiche.
Problèmes courants
Chaque frappe est une requête. Voir ci-dessus.
Rien n'apparaît pour une requête de deux lettres. Gardez le seuil de trois caractères. Les requêtes courtes correspondent à presque tout et n'aident personne.
Les résultats sont dans la mauvaise langue. Passez lang: "fr" pour obtenir les noms français
là où la fiche en a un. Sans cela, la passerelle suit l'en-tête Accept-Language de la requête.
Pour aller plus loin
- Autocomplétion pour la version sans framework
- Ajouter une carte à Vue pour la carte sur laquelle poser ceci
- API de géocodage pour les quatre points de terminaison et le classement