Ajouter une carte à Vue

Vue compte plusieurs bibliothèques de composants MapLibre, et elles résolvent la moitié « moteur de rendu ». unmap est l'autre moitié : les tuiles, les styles, le géocodage et les itinéraires que ce moteur dessine, sur une seule clé. Le composable vous remet l'objet carte MapLibre au lieu de l'envelopper, ce qui permet d'utiliser les deux ensemble.

Sur Nuxt, lisez plutôt Ajouter une carte à Nuxt : les imports automatiques et le SSR changent la réponse.

Installation

Registre copie un UnmapMap.vue dans votre projet via shadcn-vue, où il suit vos jetons de design et où le fichier vous appartient. Il faut un projet avec un components.json.

Paquet installe @unmap/vue et vous donne des composables, ce qui est le bon niveau quand la carte s'insère dans une interface que vous avez déjà construite.

npx @unmap/cli add map

Le composant

<script setup lang="ts">
import { UnmapMap } from "@/components/ui/map";
 
const apiKey = import.meta.env.VITE_UNMAP_KEY as string;
</script>
 
<template>
  <div class="h-dvh">
    <UnmapMap :api-key="apiKey" :center="[-114.07, 51.05]" :zoom="11" class="h-full" />
  </div>
</template>

La clé ne s'écrit pas pareil sur les deux voies, et ce n'est pas un hasard. Le composant copié prend api-key, parce que c'est un composant et que Vue réserve key comme attribut spécial. Le composable prend key, comme l'option du SDK partout ailleurs. Passer apiKey au composable donne une carte non authentifiée et un 401.

Sur la voie du paquet, importez maplibre-gl/dist/maplibre-gl.css une fois dans votre fichier d'entrée. Le composant copié le fait pour vous.

Ce que renvoie le composable

mapContainer est un ref de template que vous liez à l'élément. map est un shallowRef qui contient la carte MapLibre elle-même, null tant que le client n'a pas monté, et ready passe à vrai une fois la carte créée. Surveillez ready plutôt que map s'il vous faut le premier moment sûr pour ajouter une source.

<script setup lang="ts">
import { watch } from "vue";
import { useUnmap } from "@unmap/vue";
 
const { mapContainer, map, ready } = useUnmap({
  key: import.meta.env.VITE_UNMAP_KEY as string,
  center: [-114.07, 51.05],
  zoom: 11,
});
 
watch(ready, (isReady) => {
  if (!isReady || !map.value) return;
  map.value.addSource("sites", { type: "geojson", data: { type: "FeatureCollection", features: [] } });
  map.value.addLayer({ id: "sites", type: "circle", source: "sites" });
});
</script>
 
<template>
  <div ref="mapContainer" style="height: 100dvh" />
</template>

Le composable est sûr en SSR par lui-même : la carte est créée dans onMounted derrière une garde typeof window, et le paquet maplibre-gl est importé paresseusement, si bien qu'importer le composable pendant le SSR n'entraîne rien qui touche au DOM.

Où vit la clé

Vite insère dans le paquet navigateur tout ce qui est préfixé VITE_. C'est correct pour une clé de carte : une clé utilisée par une carte dans un navigateur est lisible par quiconque charge la page, chez tous les fournisseurs. Restreignez-la à vos origines de production dans le tableau de bord plutôt que de tenter de la cacher.

# .env
VITE_UNMAP_KEY=um_live_...

Problèmes courants

La carte est une boîte vide. Le conteneur n'a pas de hauteur. MapLibre mesure l'élément qu'on lui donne, et un élément de zéro pixel ne signale aucune erreur.

Un 401 sur chaque tuile. Vous avez passé apiKey au composable, qui prend key. Voir ci-dessus.

map.value est null dans onMounted. La carte est créée dans le onMounted du composable, et l'ordre entre les deux n'est pas garanti. Surveillez ready à la place.

Pour aller plus loin