经纬志
首页 / MapLibre / API 文档

setFeatureState

先看结论

给单个要素挂一份运行期状态,样式里用 feature-state 读取,改状态不动数据源。

最后验证 2026-11-03 · MapLibre GL JS 4.x · 更新 2026-10-29 · 引用本文
map.setFeatureState(target, state) → this

参数

参数类型说明
target.sourcestring源 id,必填
target.sourceLayerstring矢量瓦片内的图层名
target.idstring | number要素 id,必须与源中的 id 完全一致
stateobject键值对,值为字符串、数字或布尔

配套方法

方法说明
setFeatureState(target, state)合并写入,同名键覆盖
getFeatureState(target)取回当前状态对象,没有时为空对象
removeFeatureState(target, key?)删除单个键;省略 key 时清空整个状态

样式读取状态

map.addLayer({
  id: 'district-fill',
  type: 'fill',
  source: 'districts',
  paint: {
    'fill-color': [
      'case',
      ['boolean', ['feature-state', 'selected'], false],
      '#ff8a3d',
      '#1f5fd0'
    ],
    'fill-opacity': [
      'case',
      ['boolean', ['feature-state', 'hover'], false],
      0.55,
      0.2
    ]
  }
});

未设置的键返回 null,用 boolean 转换时给第二个参数作默认值, 否则表达式会因为类型不匹配而整层不渲染。

悬停高亮

var hoveredId = null;

map.on('mousemove', 'district-fill', function (e) {
  if (!e.features.length) { return; }

  var id = e.features[0].id;

  if (id === hoveredId) { return; }

  if (hoveredId !== null) {
    map.removeFeatureState({ source: 'districts', id: hoveredId }, 'hover');
  }

  hoveredId = id;
  map.setFeatureState({ source: 'districts', id: id }, { hover: true });
  map.getCanvas().style.cursor = 'pointer';
});

map.on('mouseleave', 'district-fill', function () {
  if (hoveredId !== null) {
    map.removeFeatureState({ source: 'districts', id: hoveredId }, 'hover');
    hoveredId = null;
  }
  map.getCanvas().style.cursor = '';
});

鼠标每次移动都会触发 mousemove,先用 id 判重, 避免对同一个要素反复写入状态。

要素 id 从哪来

数据源id 来源
GeoJSON,要素自带 id直接用该值
GeoJSON,id 在属性里源配置 promoteId: 'code',把属性提升为 id
GeoJSON,两者都没有配置 generateId: true,由客户端按顺序生成
矢量瓦片瓦片内的要素 id,配合 sourceLayer 使用
map.addSource('districts', {
  type: 'geojson',
  data: districtGeoJSON,
  promoteId: 'code'
});

回调里拿到的 e.features[0].id 就是提升后的值。 在 JS 里用数字与字符串比较要小心:promoteId 保留了原始类型, 源里是数字就不要用字符串去匹配。

状态的生命周期

setData 替换数据时,只要要素 id 不变,状态会保留; 要素被删掉后状态随之失效。setStyle 重建源,状态全部丢失, 切换主题后需要重新设置当前选中项。

状态不参与查询结果,queryRenderedFeatures 返回的 properties 里看不到它。需要读取时用 getFeatureState。

状态值只放简单类型。 嵌套对象、数组与函数不会参与表达式求值,写进去也读不出来。 需要复合状态时拆成多个布尔或数字键。

引用本文

经纬志(2026)。《setFeatureState》。https://www.jingweizhi.com/maplibre/api/set-feature-state.html(访问日期 2026-11-03)。