---
title: "MapboxDrawControl"
description: "基于 mapbox-gl-draw 的声明式绘制控件，v-model 受控要素与模式，并暴露命令式实例方法。"
seo_title: "MapboxDrawControl Component"
seo_description: "Declarative drawing control built on mapbox-gl-draw, with v-model features and mode plus imperative instance methods."
canonical_url: "https://mapbox.mhaibaraai.cn/docs/extensions/draw"
---
# MapboxDrawControl

> 基于 mapbox-gl-draw 的声明式绘制控件，v-model 受控要素与模式，并暴露命令式实例方法。

## 简介

`MapboxDrawControl` 基于 [mapbox-gl-draw](https://github.com/mapbox/mapbox-gl-draw){rel="[\"nofollow\"]"} 提供声明式绘制：`v-model:features` 受控要素集合（赋值即导入、绘制即回写）、`v-model:mode` 当前模式；触发 create / update / delete / selectionchange / modechange 事件；并经 `defineExpose` 暴露命令式方法。子组件可用 [useMapboxDraw](/docs/composables/use-mapbox-draw) 注入绘制上下文；父地图设置 `map-id` 后，该 composable 亦可在组件树外按 id 驱动绘制。

## 用法

用内置工具栏绘制点 / 线 / 面，`v-model:features` 实时回写要素数：

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

const features = ref<Feature[]>([])
</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" />
    </MapboxMap>
    <div class="absolute top-2 right-2 z-10 rounded bg-default/90 px-2 py-1 text-xs text-default ring ring-default">
      已绘制 {{ features.length }} 个要素
    </div>
  </div>
</template>
```

## 示例

### 命令式操作

经 [`useTemplateRef`](https://vuejs.org/api/composition-api-helpers.html#usetemplateref){rel="[\"nofollow\"]"} 取实例，调用 `changeMode` / `deleteAll`（已关闭默认工具栏）：

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

const features = ref<Feature[]>([])
const drawRef = useTemplateRef('drawRef')

function draw(mode: string) {
  drawRef.value?.changeMode(mode)
}
</script>

<template>
  <div class="flex h-115 w-full flex-col gap-2">
    <div class="flex flex-wrap items-center gap-2">
      <UButton size="xs" color="neutral" variant="subtle" @click="draw('draw_point')">
        点
      </UButton>
      <UButton size="xs" color="neutral" variant="subtle" @click="draw('draw_line_string')">
        线
      </UButton>
      <UButton size="xs" color="neutral" variant="subtle" @click="draw('draw_polygon')">
        面
      </UButton>
      <UButton size="xs" color="error" variant="subtle" @click="drawRef?.deleteAll()">
        清空
      </UButton>
      <span class="ml-auto text-xs text-muted">{{ features.length }} 个要素</span>
    </div>
    <div class="relative flex-1 overflow-hidden rounded-(--ui-radius) border border-default">
      <MapboxMap :options="{ style: 'mapbox://styles/mapbox/light-v11', center: [116.397, 39.908], zoom: 11 }">
        <MapboxDrawControl ref="drawRef" v-model:features="features" :options="{ displayControlsDefault: false }" />
      </MapboxMap>
    </div>
  </div>
</template>
```

## API

### Props

```ts
/**
 * Props for the MapboxDrawControl component
 */
interface MapboxDrawControlProps {
  /**
   * 控件停靠位置；省略用地图默认位置
   */
  position?: mapboxgl.ControlPosition | undefined;
  /**
   * MapboxDraw 构造选项
   */
  options?: MapboxDraw.MapboxDrawOptions | undefined;
  features?: GeoJSON.Feature<GeoJSON.Geometry, GeoJSON.GeoJsonProperties>[] | undefined;
  mode?: string | undefined;
}
```

### Emits

```ts
/**
 * Emitted events for the MapboxDrawControl component
 */
interface MapboxDrawControlEmits {
  selectionchange: (payload: [features: GeoJSON.Feature<GeoJSON.Geometry, GeoJSON.GeoJsonProperties>[]]) => void;
  update:features: (payload: [value: GeoJSON.Feature<GeoJSON.Geometry, GeoJSON.GeoJsonProperties>[] | undefined]) => void;
  update:mode: (payload: [value: string | undefined]) => void;
  create: (payload: [features: GeoJSON.Feature<GeoJSON.Geometry, GeoJSON.GeoJsonProperties>[]]) => void;
  update: (payload: [features: GeoJSON.Feature<GeoJSON.Geometry, GeoJSON.GeoJsonProperties>[]]) => void;
  delete: (payload: [features: GeoJSON.Feature<GeoJSON.Geometry, GeoJSON.GeoJsonProperties>[]]) => void;
  modechange: (payload: [mode: string]) => void;
}
```

### Slots

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

### Expose

通过 [`useTemplateRef`](https://vuejs.org/api/composition-api-helpers.html#usetemplateref){rel="[\"nofollow\"]"} 访问组件实例。

| Name                 | Type                                                                                                       |
| -------------------- | ---------------------------------------------------------------------------------------------------------- |
| `draw`               | `Readonly<Ref<MapboxDraw | undefined>>`   
 底层 MapboxDraw 实例引用；挂载前为 undefined                              |
| `whenReady`          | `() => Promise<MapboxDraw>`   
 绘制实例就绪时 resolve                                                            |
| `getAll`             | `() => FeatureCollection | undefined`   
 当前全部要素集合                                                         |
| `getMode`            | `() => string | undefined`   
 当前绘制模式                                                                      |
| `add`                | `(geojson: Feature | FeatureCollection | Geometry) => Promise<string[]>`   
 添加要素并同步模型，返回要素 id 列表          |
| `deleteAll`          | `() => Promise<void>`   
 清空全部要素并同步模型                                                                      |
| `changeMode`         | `(mode: string) => Promise<void>`   
 切换绘制模式并同步模型                                                          |
| `setFeatureProperty` | `(featureId: string, property: string, value: unknown) => Promise<void>`   
 设置要素 user\_\* 属性（驱动主题样式）并同步模型 |

## Changelog

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


## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
