---
title: "useMapboxDraw"
description: "Access the MapboxDrawControl context to control drawing from a child component or from outside the map tree."
canonical_url: "https://mapbox.mhaibaraai.cn/en/docs/composables/use-mapbox-draw"
---
# useMapboxDraw

> Access the MapboxDrawControl context to control drawing from a child component or from outside the map tree.

## Introduction

`useMapboxDraw` returns the draw context of a `<MapboxDrawControl>`. Write operations (`changeMode` / `add` / `deleteAll` / `setFeatureProperty`) return a `Promise`, await the instance internally, and keep the control's `v-model:features` and `v-model:mode` in sync. Read operations (`getAll` / `getMode`) return synchronously, or `undefined` before the instance is ready. The `draw` field keeps the raw [MapboxDraw](https://github.com/mapbox/mapbox-gl-draw) instance as an escape hatch.

> [!NOTE]
> 
> When used outside a 
> 
> <MapboxDrawControl>
> 
>  subtree, pass 
> 
> options.mapId
> 
>  to target a map. That map must set an explicit 
> 
> map-id
> 
> , otherwise it is never added to the registry.

> [!WARNING]
> 
> Breaking change in 1.2.0
> 
> : 
> 
> useMapboxDraw()
> 
>  now returns a draw context object instead of 
> 
> ShallowRef<MapboxDraw | undefined>
> 
> . Replace 
> 
> draw.value?.changeMode(m)
> 
>  with 
> 
> const { changeMode } = useMapboxDraw()
> 
>  and 
> 
> await changeMode(m)
> 
> ; use 
> 
> const { draw } = useMapboxDraw()
> 
>  if you still need the raw instance. Switching to the context methods also fixes the model mismatch where calling 
> 
> deleteAll()
> 
>  on the raw instance never wrote back to 
> 
> v-model:features
> 
> .

## Usage

A child component injects the context via `useMapboxDraw()` and switches draw modes; feature count is written back via the control's `v-model:features`:

```vue [UseMapboxDrawExample.vue]
<script setup lang="ts">
import { defineComponent, h } from 'vue'
import type { Feature } from 'geojson'

const features = ref<Feature[]>([])

// 子组件位于 <MapboxDrawControl> 子树内，经 useMapboxDraw() 注入绘制上下文并切换模式
const DrawModes = defineComponent({
  name: 'DrawModes',
  setup() {
    const { changeMode } = useMapboxDraw()

    const button = (label: string, mode: string) =>
      h('button', {
        class: 'rounded bg-default/90 px-2 py-1 text-xs text-default ring ring-default hover:bg-elevated',
        onClick: () => changeMode(mode)
      }, label)

    return () => h('div', { class: 'absolute bottom-2 left-2 z-10 flex gap-1' }, [
      button('画点', 'draw_point'),
      button('画线', 'draw_line_string'),
      button('画面', 'draw_polygon')
    ])
  }
})
</script>

<template>
  <div class="relative h-115 w-full overflow-hidden rounded-(--ui-radius) border border-default">
    <MapboxMap :options="{ style: 'mapbox://styles/mapbox/light-v11', center: [116.397, 39.908], zoom: 11 }">
      <MapboxDrawControl v-model:features="features" position="top-left">
        <DrawModes />
      </MapboxDrawControl>
    </MapboxMap>
    <div class="absolute right-2 top-2 z-10 rounded bg-default/90 px-2 py-1 text-xs text-default ring ring-default">
      已绘制 {{ features.length }} 个要素
    </div>
  </div>
</template>
```

## Examples

### Driving from outside the map tree `v1.2.0+`

The toolbar lives outside `<MapboxMap>` and drives drawing by looking up the registry with `options.mapId`. This lets global panels and layout-level components issue draw commands without joining the map component tree:

```vue [UseMapboxDrawRemoteExample.vue]
<script setup lang="ts">
import type { Feature } from 'geojson'

const MAP_ID = 'docs-draw-remote'

const features = ref<Feature[]>([])
const mode = ref('simple_select')

// 工具栏位于 <MapboxMap> 之外，按 mapId 查注册表驱动绘制
const { changeMode, deleteAll } = useMapboxDraw({ mapId: MAP_ID })
</script>

<template>
  <div class="flex flex-col gap-2 w-full">
    <div class="flex flex-wrap gap-1">
      <UButton size="xs" variant="soft" @click="changeMode('draw_point')">
        画点
      </UButton>
      <UButton size="xs" variant="soft" @click="changeMode('draw_line_string')">
        画线
      </UButton>
      <UButton size="xs" variant="soft" @click="changeMode('draw_polygon')">
        画面
      </UButton>
      <UButton size="xs" color="error" variant="soft" :disabled="!features.length" @click="deleteAll">
        清空
      </UButton>
      <span class="ml-auto self-center text-xs text-muted">
        模式 {{ mode }}，已绘制 {{ features.length }} 个要素
      </span>
    </div>

    <MapboxMap
      class="h-115"
      :map-id="MAP_ID"
      :options="{ style: 'mapbox://styles/mapbox/light-v11', center: [116.397, 39.908], zoom: 11 }"
    >
      <MapboxDrawControl
        v-model:features="features"
        v-model:mode="mode"
        position="top-left"
        :options="{
          displayControlsDefault: false,
          controls: { polygon: true, line_string: true, point: true, trash: true }
        }"
      />
    </MapboxMap>
  </div>
</template>
```

## API

### `useMapboxDraw()`

Returns the draw context.

**options.mapId** (`string`): Target map id; required when used outside a <MapboxDrawControl> subtree. When omitted, the nearest control is injected, and a missing one throws.

Returns `MapboxDrawContext`:

**mapId** (`string`): Id of the owning map.

**draw** (`Readonly<Ref<MapboxDraw | undefined>>`): The draw instance; defined once the control mounts and the map has loaded.

**whenReady** (`() => Promise<MapboxDraw>`): Resolves once the instance is ready. Rejects when called across the tree for a mapId with no registered control.

**changeMode** (`(mode: string) => Promise<void>`): Switches the draw mode and writes back to v-model:mode.

**add** (`(geojson: Feature | FeatureCollection | Geometry) => Promise<string[]>`): Adds features, writes back to v-model:features, and returns the feature ids.

**deleteAll** (`() => Promise<void>`): Removes all features and writes back to v-model:features.

**setFeatureProperty** (`(featureId: string, property: string, value: unknown) => Promise<void>`): Sets a feature's user_* property (driver theme styling) and triggers a redraw.

**getAll** (`() => FeatureCollection | undefined`): The current feature collection; undefined before the instance is ready.

**getMode** (`() => string | undefined`): The current draw mode; undefined before the instance is ready.

Across the tree, when the target `mapId` has no registered control: write operations warn and no-op, read operations return `undefined` silently (they are often re-evaluated inside a `computed`), and only `whenReady()` throws an explicit error.

## Changelog

See commit history for [src/runtime/composables/useMapboxDraw.ts](https://github.com/mhaibaraai/movk-mapbox/commits/main/src/runtime/composables/useMapboxDraw.ts).


## Sitemap

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