useFeatureState

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

简介

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

要素必须带 id:在 source 上配置 generateId: truepromoteId,否则 feature-state 无法定位要素。

用法

悬浮高亮、点击选中,fill-opacityfeature-state 表达式分级驱动:

悬浮:无选中:无
<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.9), block('B 区', 116.4, 39.9), block('C 区', 116.46, 39.9)]
}

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

No recent changes
Copyright © 2026 - 2026 YiXuan - MIT License