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

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

## Introduction

`useMaplibreDraw` returns the draw context of a `<MaplibreDrawControl>`. 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 [TerraDraw](https://github.com/JamesLMilner/terra-draw) instance as an escape hatch.

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

## Usage

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

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

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

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

    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('画点', 'point'),
      button('画线', 'linestring'),
      button('画面', 'polygon')
    ])
  }
})
</script>

<template>
  <div class="relative h-115 w-full overflow-hidden rounded-(--ui-radius) border border-default">
    <MaplibreMap :options="{ style: 'https://tiles.openfreemap.org/styles/positron', center: [116.397, 39.908], zoom: 11 }">
      <MaplibreDrawControl v-model:features="features" position="top-left">
        <DrawModes />
      </MaplibreDrawControl>
    </MaplibreMap>
    <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

The toolbar lives outside `<MaplibreMap>` 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 [UseMaplibreDrawRemoteExample.vue]
<script setup lang="ts">
import type { Feature } from 'geojson'

const MAP_ID = 'docs-draw-remote'

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

// 工具栏位于 <MaplibreMap> 之外，按 mapId 查注册表驱动绘制
const { changeMode, deleteAll } = useMaplibreDraw({ 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('point')">
        画点
      </UButton>
      <UButton size="xs" variant="soft" @click="changeMode('linestring')">
        画线
      </UButton>
      <UButton size="xs" variant="soft" @click="changeMode('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>

    <MaplibreMap
      class="h-115"
      :map-id="MAP_ID"
      :options="{ style: 'https://tiles.openfreemap.org/styles/positron', center: [116.397, 39.908], zoom: 11 }"
    >
      <MaplibreDrawControl
        v-model:features="features"
        v-model:mode="mode"
        position="top-left"
        :modes="['select', 'point', 'linestring', 'polygon']"
      />
    </MaplibreMap>
  </div>
</template>
```

## API

### `useMaplibreDraw()`

Returns the draw context.

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

Returns `MaplibreDrawContext`:

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

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

**whenReady** (`() => Promise<TerraDraw>`): 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<FeatureId[]>`): Adds features and writes back to v-model:features; generates missing ids, infers a missing properties.mode from the geometry type, and returns the ids that were added.

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

**setFeatureProperty** (`(featureId: FeatureId, property: string, value: unknown) => Promise<void>`): Sets a feature property (for example color to override the theme) and writes back to v-model:features.

**getAll** (`() => FeatureCollection | undefined`): Completed features, excluding in-progress features and guidance points; 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/useMaplibreDraw.ts](https://github.com/mhaibaraai/movk-maplibre/commits/main/src/runtime/composables/useMaplibreDraw.ts).


## Sitemap

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