<script setup lang="ts">
import { VMap } from '@geoql/v-maplibre';
import type { MapOptions } from 'maplibre-gl';
const mapOptions: MapOptions = {
style: 'https://demotiles.maplibre.org/style.json',
center: [-74.5, 40],
zoom: 9,
};
const handleMapLoad = (map) => {
console.log('Map loaded!', map);
};
</script>
<template>
<VMap
:options="mapOptions"
@loaded="handleMapLoad"
style="height: 500px"
></VMap>
</template>
MapOptionstrue{ container: 'map' }MapLibre GL map options. See MapLibre GL documentation for all available options.
Common options include:
style: URL to the map style or a style objectcenter: Initial map center [lng, lat]zoom: Initial zoom levelbearing: Initial bearing (rotation)pitch: Initial pitch (tilt)minZoom: Minimum zoom levelmaxZoom: Maximum zoom levelmaxBounds: Map bounds constraintbooleanfalsefalseEnable PMTiles protocol support. Set to true if you plan to use PMTiles layers.
<VMap :options="mapOptions" support-pmtiles></VMap>
Emitted when the map has finished loading.
Map - The MapLibre GL Map instance<VMap @loaded="(map) => console.log('Map ready', map)"></VMap>
The VMap component forwards all MapLibre GL map events. You can listen to any map event using the @ directive:
<VMap
:options="mapOptions"
@click="handleClick"
@move="handleMove"
@zoom="handleZoom"
@load="handleLoad"
></VMap>
Common events include:
@load - Map loaded@click - Map clicked@dblclick - Map double-clicked@move - Map moved@movestart - Map move started@moveend - Map move ended@zoom - Map zoomed@zoomstart - Zoom started@zoomend - Zoom endedSee MapLibre GL Events for the complete list.
The default slot is used to nest child components like markers, popups, layers, and controls.
<VMap :options="mapOptions">
<VMarker :lng-lat="[0, 0]" />
<VLayerMaplibreGeojson :source="source" :layer="layer" />
<VControlNavigation />
</VMap>
Child components can access the map instance using Vue's provide/inject API:
<script setup lang="ts">
import { inject } from 'vue';
import { MapKey } from '@geoql/v-maplibre/utils/symbols';
import type { Map } from 'maplibre-gl';
import type { Ref } from 'vue';
const map = inject<Ref<Map | null>>(MapKey);
// Use the map instance
watch(map, (mapInstance) => {
if (mapInstance) {
console.log('Map instance available', mapInstance);
}
});
</script>
The component is fully typed with TypeScript. Import types from maplibre-gl:
import type { MapOptions, Map } from 'maplibre-gl';
<script setup lang="ts">
import { VMap } from '@geoql/v-maplibre';
const customStyle = {
version: 8,
sources: {
osm: {
type: 'raster',
tiles: ['https://tile.openstreetmap.org/{z}/{x}/{y}.png'],
tileSize: 256,
attribution: '© OpenStreetMap Contributors',
},
},
layers: [
{
id: 'osm',
type: 'raster',
source: 'osm',
},
],
};
const mapOptions = {
style: customStyle,
center: [0, 0],
zoom: 2,
};
</script>
<template>
<VMap :options="mapOptions" style="height: 100vh"></VMap>
</template>
<script setup lang="ts">
import { VMap } from '@geoql/v-maplibre';
import type { LngLatBoundsLike } from 'maplibre-gl';
const bounds: LngLatBoundsLike = [
[-74.047285, 40.679548], // Southwest
[-73.907005, 40.882214], // Northeast
];
const mapOptions = {
style: 'https://demotiles.maplibre.org/style.json',
bounds,
fitBoundsOptions: {
padding: 20,
},
};
</script>
<template>
<VMap :options="mapOptions" style="height: 500px"></VMap>
</template>