---
title: "MapboxMap"
description: "The root component that creates a Mapbox GL instance on the client and distributes it via MapboxContext, with v-model camera two-way binding and cross-route persistence."
canonical_url: "https://mapbox.mhaibaraai.cn/en/docs/core/map"
---
# MapboxMap

> The root component that creates a Mapbox GL instance on the client and distributes it via MapboxContext, with v-model camera two-way binding and cross-route persistence.

## Introduction

`MapboxMap` is the root of everything: it creates the `mapbox-gl` instance on the client in `onMounted`, distributes a [MapboxContext](https://mapbox.mhaibaraai.cn/docs/getting-started/concepts) via `provide`, and child components access it through `useMap()`. The container is sized at `100%` width and height — make sure the parent has an explicit height (examples use `h-115` throughout).

> [!NOTE]
> 
> The component is SSR-safe and does not require a 
> 
> <ClientOnly>
> 
>  wrapper. When 
> 
> accessToken
> 
>  is omitted, it falls back to the globally injected token from the module config.

> [!NOTE]
> 
> hideLogo
> 
>  only hides the Mapbox wordmark in the bottom-left corner; attribution in the bottom-right is unaffected (control it via 
> 
> options.attributionControl
> 
>  or 
> 
> MapboxAttributionControl
> 
> ). The switch targets self-hosted or third-party basemaps such as Tianditu — when using official Mapbox basemaps and data, attribution display must comply with the Mapbox Terms of Service.

## Usage

`center` / `zoom` / `bearing` / `pitch` all support `v-model`: the component compares the bound value against the current map state and only pushes an update when they differ, breaking the "model → map → event → model" feedback loop. Dragging or zooming the map keeps the bound values in sync.

```vue [MapBasicExample.vue]
<script setup lang="ts">
const center = ref<[number, number]>([116.397, 39.908])
const zoom = ref(9)
</script>

<template>
  <div class="h-115 w-full overflow-hidden rounded-(--ui-radius) border border-default">
    <MapboxMap
      v-model:center="center"
      v-model:zoom="zoom"
      :options="{ style: 'mapbox://styles/mapbox/streets-v12' }"
    >
      <MapboxNavigationControl position="top-right" />
    </MapboxMap>
  </div>
</template>
```

## Examples

### Camera Transitions

Use `flyTo` from `useMapboxCamera` to smoothly animate between multiple preset camera positions:

```vue [MapCameraExample.vue]
<script setup lang="ts">
import type { LngLatLike } from 'mapbox-gl'

const mapId = 'camera-demo'
const { flyTo } = useMapboxCamera({ mapId })

const presets: { label: string, center: LngLatLike, zoom: number }[] = [
  { label: 'Beijing', center: [116.397, 39.908], zoom: 10 },
  { label: 'Shanghai', center: [121.473, 31.230], zoom: 10 },
  { label: 'Shenzhen', center: [114.057, 22.543], zoom: 10 }
]

function go(center: LngLatLike, zoom: number) {
  flyTo({ center, zoom, duration: 2000 })
}
</script>

<template>
  <div class="h-115 w-full overflow-hidden rounded-(--ui-radius) border border-default">
    <MapboxMap
      :map-id="mapId"
      :options="{ style: 'mapbox://styles/mapbox/streets-v12', center: [116.397, 39.908], zoom: 10 }"
    >
      <div class="absolute left-3 top-3 z-10 flex flex-wrap gap-2">
        <UButton
          v-for="p in presets"
          :key="p.label"
          size="xs"
          color="neutral"
          variant="solid"
          @click="go(p.center, p.zoom)"
        >
          {{ p.label }}
        </UButton>
      </div>
    </MapboxMap>
  </div>
</template>
```

## API

### Props

```ts
/**
 * Props for the MapboxMap component
 */
interface MapboxMapProps {
  /**
   * 地图 id；省略时自动生成。提供后可经 useMapbox(id) 外部访问
   */
  mapId?: string | undefined;
  /**
   * mapbox-gl Map 初始化选项（container 由组件接管）
   */
  options?: MapboxMapOptions | undefined;
  /**
   * 覆盖全局 access token
   */
  accessToken?: string | undefined;
  /**
   * 卸载时不销毁实例，配合 keepalive / `<keep-alive>` 跨路由复用
   * @default "false"
   */
  persistent?: boolean | undefined;
  /**
   * 隐藏地图左下角的 Mapbox 字标
   * @default "false"
   */
  hideLogo?: boolean | undefined;
  center?: mapboxgl.LngLatLike | undefined;
  zoom?: number | undefined;
  bearing?: number | undefined;
  pitch?: number | undefined;
}
```

### Emits

`update:center` / `update:zoom` / `update:bearing` / `update:pitch` are the camera `v-model` sync events. All other events are forwarded mapbox-gl map events.

```ts
/**
 * Emitted events for the MapboxMap component
 */
interface MapboxMapEmits {
  click: (payload: [event: mapboxgl.MapMouseEvent]) => void;
  contextmenu: (payload: [event: mapboxgl.MapMouseEvent]) => void;
  dblclick: (payload: [event: mapboxgl.MapMouseEvent]) => void;
  dragend: (payload: [event: { type: "dragend"; target: mapboxgl.Map; } & { originalEvent?: MouseEvent | TouchEvent | undefined; }]) => void;
  error: (payload: [event: { type: "error"; target: mapboxgl.Map; } & { error: Error; }]) => void;
  load: (payload: [map: mapboxgl.Map]) => void;
  mousedown: (payload: [event: mapboxgl.MapMouseEvent]) => void;
  mousemove: (payload: [event: mapboxgl.MapMouseEvent]) => void;
  mouseup: (payload: [event: mapboxgl.MapMouseEvent]) => void;
  update:center: (payload: [value: mapboxgl.LngLatLike | undefined]) => void;
  update:zoom: (payload: [value: number | undefined]) => void;
  update:bearing: (payload: [value: number | undefined]) => void;
  update:pitch: (payload: [value: number | undefined]) => void;
  idle: (payload: [map: mapboxgl.Map]) => void;
  movestart: (payload: [event: { type: "movestart"; target: mapboxgl.Map; } & { originalEvent?: MouseEvent | TouchEvent | WheelEvent | undefined; }]) => void;
  moveend: (payload: [event: { type: "moveend"; target: mapboxgl.Map; } & { originalEvent?: MouseEvent | TouchEvent | WheelEvent | undefined; }]) => void;
  zoomstart: (payload: [event: { type: "zoomstart"; target: mapboxgl.Map; }]) => void;
  zoomend: (payload: [event: { type: "zoomend"; target: mapboxgl.Map; }]) => void;
  rotateend: (payload: [event: { type: "rotateend"; target: mapboxgl.Map; } & { originalEvent?: MouseEvent | TouchEvent | undefined; }]) => void;
  pitchend: (payload: [event: { type: "pitchend"; target: mapboxgl.Map; }]) => void;
  styledata: (payload: [event: { type: "styledata"; target: mapboxgl.Map; } & mapboxgl.MapStyleDataEvent]) => void;
  sourcedata: (payload: [event: { type: "sourcedata"; target: mapboxgl.Map; } & mapboxgl.MapSourceDataEvent]) => void;
}
```

### Slots

```ts
/**
 * Slots for the MapboxMap component
 */
interface MapboxMapSlots {
  default(): any;
}
```

## Changelog

See commit history for [src/runtime/components/MapboxMap.vue](https://github.com/mhaibaraai/movk-mapbox/commits/main/src/runtime/components/MapboxMap.vue).


## Sitemap

See the full [sitemap](https://mapbox.mhaibaraai.cn/sitemap.md) for all pages.
