Skip to content

Vue 3 组件(@geoverse/vue)

@geoverse/vue 是 GeoVerse 的官方 Vue 3 组件层:把 core 的命令式 API 包装成声明式组件树命令式 composable,让你用模板和响应式数据驱动地图。它是一层薄绑定——不复制任何地图逻辑,坐标 / 聚合 / 绘制等全部留在 core。

React 用户见 React 组件(@geoverse/react),组件清单与事件映射约定与本包 1:1 对齐。

安装

shell
pnpm add @geoverse/vue geoverse ol

geoverseolvue 均为 peerDependencies(与宿主共享实例)。要素变换组件 <GvTransform> 额外依赖可选 peer ol-ext,用到时再装 pnpm add ol-ext

快速上手(声明式)

vue
<script setup lang="ts">
import { ref } from 'vue';
import { GvMap, GvVectorLayer, GvMarker, GvInfoWindow } from '@geoverse/vue';

const center = ref([118.18, 24.49]);
const zoom = ref(12);
const open = ref(false);
</script>

<template>
  <GvMap
    style="height: 480px"
    base="gd-vec"
    v-model:center="center"
    v-model:zoom="zoom"
    scale-line
  >
    <GvVectorLayer>
      <GvMarker
        :options="{ position: [118.18, 24.49], color: 'red', size: 8 }"
        @click="open = true"
      />
    </GvVectorLayer>

    <GvInfoWindow v-model:open="open" :position="[118.18, 24.49]">
      <div class="popup">插槽内容,点击标注弹出</div>
    </GvInfoWindow>
  </GvMap>
</template>
  • <GvMap>onMounted 内创建 GMap(SSR 安全),就绪后才渲染子组件并 provide 给它们;
  • center / zoom 受控,支持 v-model;底图 base 变化走 switchBase
  • 要素组件必须置于 <GvVectorLayer> 内,否则抛出清晰错误。

命令式(composable)

需要完全控制时用 useMap(),在自己的容器上创建 / 销毁地图:

vue
<script setup lang="ts">
import { ref } from 'vue';
import { useMap } from '@geoverse/vue';
import { Marker } from 'geoverse';

const el = ref<HTMLElement>();
const { map } = useMap({ base: 'gd-vec', center: [118.18, 24.49], zoom: 12 }, el);

function addPoint() {
  // map.value 是 markRaw 的 GMap 实例,可直接调用任意 core API
  map.value?.addLayer(/* ... */);
}
</script>

<template>
  <div ref="el" style="height: 480px"></div>
</template>

<GvMap> 子树内则用 injectMap() 取父地图。

全局注册(可选)

ts
import { createApp } from 'vue';
import { GeoVerseVue } from '@geoverse/vue';

createApp(App).use(GeoVerseVue); // 批量注册全部组件

也可只具名导入用到的组件,无需安装插件(利于 tree-shaking)。

组件一览

类别组件
容器GvMap
图层GvVectorLayerGvHeatLayerGvImageLayerGvCustomBaseLayerGvTrafficLayerGvClusterLayerGvSuperClusterLayerGvMassLayerGvNameLayer
要素GvMarkerGvCircleGvPolygonGvPolyline
交互GvDrawGvMeasureGvFeatureEditorGvTransform@experimental
控件 / 弹窗GvOverviewGvInfoWindow
轨迹GvPathSimplifier

约定:图层 / 要素 / 工具组件的 options prop = 对应 core 类的构造选项map / view 由组件自动注入;事件经 emits 转发(如要素的 @click、绘制的 @complete、轨迹的 @move)。每个组件用 defineExpose 暴露底层实例(模板 ref 可取)。

受控属性与响应式更新

  • <GvMap>center / zoom 双向受控,支持 v-model;底图 base 变化触发 switchBase(切投影并重投影既有图层/要素)。
  • 要素几何受控<GvMarker :options>position<GvCircle>center<GvPolygon>/<GvPolyline>path 变化时,组件会按当前底图投影自动重投影并更新几何。坐标统一以 WGS-84 经纬度传入。
    • 几何更新按「值」比较触发(而非对象引用),因此即使用内联 :options="{ ... }"(每次渲染新对象),切底图等无关重渲染也不会误重置几何。
  • 其余「构造即生效」的选项(如样式、聚合 distance)变化时不自动响应,需要时可经组件 ref 取实例命令式更新,或重建组件。

注意事项

  • 响应式陷阱:组件内部所有 ol 派生实例(地图 / 图层 / 要素)一律 markRaw / shallowRef,绝不进入深层响应式——这是正确性前提。你自己持有这些实例时也请遵循。
  • SSR:所有实例化都在 onMounted,Nuxt 3 服务端构建安全;<GvMap> 渲染期只产出容器 DOM。
  • 挂载顺序:图层组件在 setup 阶段即把图层加入地图(早于子要素挂载),确保子要素 addFeature 时图层投影已同步、坐标不错位。
  • 卸载:子组件先移除自身(removeFeature / removeLayer),地图组件最后 destroy();定时器 / 监听 / overlay 由 core 的 destroy() 完整回收。

在线示例:仓库 examples/vue/pnpm dev:examples/vue/)。