---
title: "MaplibreLegend"
description: "图例控件，展示可见图层组的图例，由图层颜色自动推导或手动指定。"
canonical_url: "https://maplibre.mhaibaraai.cn/docs/controls/legend"
---
# MaplibreLegend

> 图例控件，展示可见图层组的图例，由图层颜色自动推导或手动指定。

## 简介

`MaplibreLegend` 展示所有可见且带 `title` 的 [`MaplibreLayerGroup`](https://maplibre.mhaibaraai.cn/docs/core/layer-group) 的图例，组隐藏后对应图例随之消失。图例项来源：

- 组的 `legend` prop，手动指定时优先使用；
- 否则由组内图层的颜色推导：字面量颜色生成一项，`match` 按取值分项，`step` 按区间分项，`interpolate` 生成渐变色带。以缩放级别为输入的表达式与其他无法识别的表达式会被跳过。

图例默认展开，点击控件外部不会收起，可以用右上角按钮收起。

## 用法

「人口密度」由 `step` 推导出分级区间，「设施」通过 `legend` prop 改写了 `match` 推导出的标签：

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

const pois: FeatureCollection = {
  type: 'FeatureCollection',
  features: [
    { type: 'Feature', properties: { kind: 'school' }, geometry: { type: 'Point', coordinates: [116.38, 39.92] } },
    { type: 'Feature', properties: { kind: 'hospital' }, geometry: { type: 'Point', coordinates: [116.42, 39.9] } }
  ]
}

const districts: FeatureCollection = {
  type: 'FeatureCollection',
  features: [
    { type: 'Feature', properties: { pop: 60 }, geometry: { type: 'Polygon', coordinates: [[[116.34, 39.88], [116.38, 39.88], [116.38, 39.91], [116.34, 39.91], [116.34, 39.88]]] } },
    { type: 'Feature', properties: { pop: 800 }, geometry: { type: 'Polygon', coordinates: [[[116.44, 39.88], [116.48, 39.88], [116.48, 39.91], [116.44, 39.91], [116.44, 39.88]]] } }
  ]
}
</script>

<template>
  <div class="h-115 w-full overflow-hidden rounded-(--ui-radius) border border-default">
    <MaplibreMap :options="{ style: 'https://tiles.openfreemap.org/styles/positron', center: [116.41, 39.91], zoom: 11.5 }">
      <!-- step 表达式推导为分级区间 -->
      <MaplibreLayerGroup title="人口密度">
        <MaplibreLayer
          layer-id="legend-districts"
          type="fill"
          :source="{ type: 'geojson', data: districts }"
          :paint="{ 'fill-color': ['step', ['get', 'pop'], '#fde68a', 100, '#f59e0b', 500, '#b45309'], 'fill-opacity': 0.6 }"
        />
      </MaplibreLayerGroup>
      <!-- match 表达式推导为分类项；legend prop 可改写标签 -->
      <MaplibreLayerGroup
        title="设施"
        :legend="[
          { label: '学校', type: 'circle', color: '#22c55e' },
          { label: '医院', type: 'circle', color: '#ef4444' }
        ]"
      >
        <MaplibreLayer
          layer-id="legend-pois"
          type="circle"
          :source="{ type: 'geojson', data: pois }"
          :paint="{ 'circle-radius': 8, 'circle-color': ['match', ['get', 'kind'], 'school', '#22c55e', 'hospital', '#ef4444', '#999'], 'circle-stroke-width': 2, 'circle-stroke-color': '#fff' }"
        />
      </MaplibreLayerGroup>
      <MaplibreLayerControl position="top-left" />
      <MaplibreLegend position="bottom-left" />
    </MaplibreMap>
  </div>
</template>
```

## API

### Props

```ts
/**
 * Props for the MaplibreLegend component
 */
interface MaplibreLegendProps {
  /**
   * 控件停靠位置；省略用地图默认位置
   */
  position?: "top-left" | "top-right" | "bottom-left" | "bottom-right" | undefined;
  /**
   * 只展示这些标题的图层组；省略展示全部
   */
  groups?: string[] | undefined;
  /**
   * 是否可折叠
   * @default true
   */
  collapsible?: boolean | undefined;
  /**
   * 折叠按钮与图例列表的无障碍标签
   * @default 'Legend'
   */
  label?: string | undefined;
  /**
   * 可折叠时的展开状态
   * @default true
   */
  open?: boolean | undefined;
}
```

### Emits

```ts
/**
 * Emitted events for the MaplibreLegend component
 */
interface MaplibreLegendEmits {
  update:open: (payload: [value: boolean]) => void;
}
```

### Slots

```ts
/**
 * Slots for the MaplibreLegend component
 */
interface MaplibreLegendSlots {
  /**
   * 自定义单个图例项
   */
  item(): any;
}
```

## Changelog

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


## Sitemap

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