---
title: "MapboxPopup"
description: "A popup that renders content through its default slot, anchored at a reactive lnglat position."
canonical_url: "https://mapbox.mhaibaraai.cn/en/docs/core/popup"
---
# MapboxPopup

> A popup that renders content through its default slot, anchored at a reactive lnglat position.

## Introduction

`MapboxPopup` anchors a popup at the specified `lnglat`, rendering arbitrary content via the default slot. The position updates reactively when `lnglat` changes, and a `close` event is emitted when the popup is dismissed.

## Usage

The default slot renders the popup content, and mapbox options such as `options.closeOnClick` are forwarded directly:

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

const lnglat = ref<LngLatLike>([116.397, 39.908])
</script>

<template>
  <div class="h-115 w-full overflow-hidden rounded-(--ui-radius) border border-default">
    <MapboxMap :options="{ style: 'mapbox://styles/mapbox/streets-v12', center: [116.397, 39.908], zoom: 13 }">
      <!-- 默认插槽渲染弹窗内容 -->
      <MapboxPopup :lnglat="lnglat" :options="{ closeOnClick: false, offset: 12 }">
        <div class="px-1 py-0.5">
          <p class="font-semibold">
            天安门
          </p>
          <p class="text-sm text-muted">
            北京市东城区
          </p>
        </div>
      </MapboxPopup>
    </MapboxMap>
  </div>
</template>
```

## Examples

### Click to Set Position

Click the map to get coordinates, assign them to `lnglat`, and the popup repositions automatically:

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

const lnglat = ref<LngLatLike | null>(null)
const label = ref('')

// 点击地图取坐标，弹窗随之定位（同一 Popup 经 watch 增量更新位置）
function onClick(event: MapEventOf<'click'>) {
  const { lng, lat } = event.lngLat
  lnglat.value = [lng, lat]
  label.value = `${lng.toFixed(4)}, ${lat.toFixed(4)}`
}
</script>

<template>
  <div class="h-115 w-full overflow-hidden rounded-(--ui-radius) border border-default">
    <MapboxMap
      :options="{ style: 'mapbox://styles/mapbox/streets-v12', center: [116.397, 39.908], zoom: 12 }"
      @click="onClick"
    >
      <MapboxPopup v-if="lnglat" :lnglat="lnglat" :options="{ offset: 8 }">
        <div class="px-1 py-0.5 text-sm">
          {{ label }}
        </div>
      </MapboxPopup>
      <div v-if="!lnglat" class="absolute left-3 top-3 z-10 rounded-(--ui-radius) border border-default bg-default/80 px-3 py-1.5 text-sm backdrop-blur">
        点击地图任意位置
      </div>
    </MapboxMap>
  </div>
</template>
```

### Multiple Popups

Render several `MapboxPopup` components with `v-for` to keep a group of popups open at once. `closeOnClick` must be disabled, otherwise a single map click dismisses the whole group:

```vue [PopupGroupExample.vue]
<script setup lang="ts">
interface Poi {
  id: string
  lnglat: [number, number]
  name: string
}

const points: Poi[] = [
  { id: 'tam', lnglat: [116.397, 39.908], name: '天安门' },
  { id: 'gm', lnglat: [116.461, 39.909], name: '国贸' },
  { id: 'zgc', lnglat: [116.316, 39.983], name: '中关村' }
]
</script>

<template>
  <div class="h-115 w-full overflow-hidden rounded-(--ui-radius) border border-default">
    <MapboxMap :options="{ style: 'mapbox://styles/mapbox/light-v11', center: [116.39, 39.94], zoom: 10.6 }">
      <MapboxPopup
        v-for="point in points"
        :key="point.id"
        :lnglat="point.lnglat"
        :options="{ closeButton: false, closeOnClick: false, offset: 12 }"
      >
        <div class="px-1 text-sm font-semibold">
          {{ point.name }}
        </div>
      </MapboxPopup>
    </MapboxMap>
  </div>
</template>
```

> [!NOTE]
> 
> MapboxTooltip
> 
>  holds a single Popup instance and cannot show several feature popups at once — its 
> 
> feature
> 
>  comes from mouse events, and the component does not hold the feature list. To keep layer-feature popups open simultaneously, iterate the source array that builds your GeoJSON and render one 
> 
> MapboxPopup
> 
>  per point. If your points are DOM markers, 
> 
> MapboxMarker
> 
>  with 
> 
> :open="true"
> 
>  is more direct.

## API

### Props

```ts
/**
 * Props for the MapboxPopup component
 */
interface MapboxPopupProps {
  /**
   * 弹窗锚定的经纬度
   */
  lnglat: mapboxgl.LngLatLike;
  /**
   * Popup 选项
   */
  options?: mapboxgl.PopupOptions | undefined;
}
```

### Emits

```ts
/**
 * Emitted events for the MapboxPopup component
 */
interface MapboxPopupEmits {
  close: (payload: []) => void;
}
```

### Slots

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

### Expose

Access the component instance via [`useTemplateRef`](https://vuejs.org/api/composition-api-helpers.html#usetemplateref).

<table>
<thead>
  <tr>
    <th>
      Name
    </th>
    
    <th>
      Type
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code className="language-ts-type shiki shiki-themes material-theme-lighter material-theme material-theme-palenight" language="ts-type" style="">
        <span class="sBMFI">
          popup
        </span>
      </code>
    </td>
    
    <td>
      <code className="language-ts-type shiki shiki-themes material-theme-lighter material-theme material-theme-palenight" language="ts-type" style="">
        <span class="sMK4o">
          ()
        </span>
        
        <span class="spNyl">
          =>
        </span>
        
        <span class="sBMFI">
          Popup
        </span>
        
        <span class="sMK4o">
          |
        </span>
        
        <span class="sBMFI">
          undefined
        </span>
      </code>
      
       <br />
      
       <p>
        Returns the underlying mapbox-gl Popup instance
      </p>
    </td>
  </tr>
</tbody>
</table>

## Changelog

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


## Sitemap

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