---
title: "useFeatureState"
description: "在目标图层上维护 feature-state 的 hover / selected 状态，驱动数据驱动样式。"
seo_title: "useFeatureState"
seo_description: "Maintain hover and selected feature-state on a target layer so paint expressions can drive styling without resetting source data."
canonical_url: "https://mapbox.mhaibaraai.cn/docs/composables/use-feature-state"
---
# useFeatureState

> 在目标图层上维护 feature-state 的 hover / selected 状态，驱动数据驱动样式。

## 简介

`useFeatureState` 在目标图层上自动维护 `feature-state` 的 hover / selected 状态：消费侧 paint 用 `['feature-state', 'hover' | 'selected']` 表达式驱动样式，无需重设 source 数据即可高亮悬浮与选中要素。返回当前悬浮 / 选中要素与清除选中方法。

> \[\!NOTE\]
> 
> 要素必须带 
> 
> id
> 
> ：在 source 上配置 
> 
> generateId: true
> 
>  或 
> 
> promoteId
> 
> ，否则 
> 
> feature-state
> 
>  无法定位要素。

## 用法

悬浮高亮、点击选中，`fill-opacity` 经 `feature-state` 表达式分级驱动：

```vue [UseFeatureStateExample.vue]
<script setup lang="ts">
import type { GeoJSONFeature } from 'mapbox-gl'
import type { Feature, FeatureCollection } from 'geojson'

const mapId = 'use-feature-state-demo'

function block(name: string, lng: number, lat: number): Feature {
  const d = 0.04
  return {
    type: 'Feature',
    properties: { name },
    geometry: { type: 'Polygon', coordinates: [[[lng, lat], [lng + d, lat], [lng + d, lat + d], [lng, lat + d], [lng, lat]]] }
  }
}

const data: FeatureCollection = {
  type: 'FeatureCollection',
  features: [block('A 区', 116.34, 39.90), block('B 区', 116.40, 39.90), block('C 区', 116.46, 39.90)]
}

const { hovered, selected, clearSelection } = useFeatureState('blocks-fill', { mapId })

const nameOf = (feature: GeoJSONFeature | undefined) => (feature?.properties?.name as string) ?? '无'
</script>

<template>
  <div class="relative h-115 w-full overflow-hidden rounded-(--ui-radius) border border-default">
    <MapboxMap :map-id="mapId" :options="{ style: 'mapbox://styles/mapbox/light-v11', center: [116.42, 39.92], zoom: 10.5 }">
      <MapboxSource source-id="blocks" :source="{ type: 'geojson', data, generateId: true }">
        <MapboxLayer
          layer-id="blocks-fill"
          type="fill"
          source="blocks"
          :paint="{
            'fill-color': '#3b82f6',
            'fill-opacity': [
              'case',
              ['boolean', ['feature-state', 'selected'], false], 0.8,
              ['boolean', ['feature-state', 'hover'], false], 0.5,
              0.2
            ]
          }"
        />
        <MapboxLayer layer-id="blocks-line" type="line" source="blocks" :paint="{ 'line-color': '#1d4ed8', 'line-width': 1 }" />
      </MapboxSource>
    </MapboxMap>
    <div class="absolute left-2 top-2 z-10 flex items-center gap-2 rounded bg-default/90 px-3 py-1.5 text-xs text-default ring ring-default">
      <span>悬浮：{{ nameOf(hovered) }}</span>
      <span>选中：{{ nameOf(selected) }}</span>
      <UButton size="xs" variant="soft" @click="clearSelection">
        清除
      </UButton>
    </div>
  </div>
</template>
```

## API

### `useFeatureState()`

在目标图层上维护交互状态。

**layerId** (`string`) *required*: 目标图层 id。

**options.mapId** (`string`): 目标地图 id；在 <MapboxMap> 子树外使用时必填。

**options.hover** (`boolean`): 维护 hover 状态，默认 true。

**options.select** (`boolean`): 维护 click 选中状态，默认 true。

**options.cursor** (`boolean`): 悬浮时设置 pointer 指针，默认 true。

返回 `UseFeatureStateReturn`：

**hovered** (`ShallowRef<GeoJSONFeature | undefined>`): 当前悬浮要素。

**selected** (`ShallowRef<GeoJSONFeature | undefined>`): 当前选中要素。

**clearSelection** (`() => void`): 清除选中。

## Changelog

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


## Sitemap

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