- 后端
- 前端
- 认证鉴权
- 应用安全
【免费下载链接】Snowy
💖国内首个国密前后分离快速开发平台💖《免费商用》,基于开源技术栈精心打造,融合Vue3+AntDesignVue4+Vite5+SpringBoot3+Mp+HuTool+Sa-Token。平台内置国密加解密功能,保障前后端数据传输安全;全面支持国产化环境,适配多种机型、中间件及数据库。特别推荐:插件提供工作流、多租户、多数据源、即时通讯等高级插件,灵活接入,让您的项目开发如虎添翼。
导读
本文围绕 Snowy 前端仓库中的百度地图封装组件展开,该组件位于snowy-admin-web/src/components/Map/baiduMap/,基于百度地图 WebGL(BMapGL)版本封装,专用于在 Vue3 + AntDesignVue4 的后台管理界面中快速完成地图展示、点/线/面覆盖物渲染与信息窗体交互。读完本文,你将掌握该组件的 Key 申请流程、全部 Prop 属性与事件、10 个暴露方法的参数结构,以及从源码层面理解其动态加载、浏览器定位与 3D 视角控制的底层实现,可直接在业务页面中落地使用。
一、组件定位:Snowy 前端的地图展示能力
Snowy 前端在snowy-admin-web/src/components/Map/目录下维护了两套地图组件:百度地图(README.md)与高德地图(gaodeMap/README.md),二者 API 风格保持一致,均由小诺开源技术封装。百度地图组件面向"地图展示"场景,其核心实现文件为 index.vue,源码注释标明其底层依赖为BMapGL(百度地图 JavaScript API GL 版,即 WebGL 渲染的 3D 地图),因此组件天然支持 2D/3D 两种视角切换、旋转与倾斜等 3D 化能力。
组件通过 Vue3<script setup>语法编写,对外暴露一组统一的覆盖物渲染方法,业务页面只需要传入结构化数据(dataArr),即可完成点标记、图标、3D 圆点、3D 图标、折线、圆形、多边形、信息窗体等各类覆盖物的渲染,无需直接接触 BMapGL 底层 API。
二、快速开始:申请 Key 与基础接入
1. 申请百度地图 Key
使用该组件的前置条件只有一个:申请百度地图开放平台的 Key(ak)。按文档指引,访问百度地图开放平台(lbsyun.baidu.com/apiconsole/center#/home)注册账号,在控制台创建应用后即可获得 Key。需要注意:本组件加载的是type=webgl的 GL 版本 API,申请应用时应选择对应的"浏览器端(JS API GL)"类型,并将ak传入api-key属性。
2. 基础使用示例
组件文档给出的最小可用写法如下(完整示例见仓库 示例页面):
<template> <baidu-map ref="map" api-key="******" @complete="handleComplete" @marker-click="handleMarkerClick" /> </template> <script setup name="exmAMap"> import BaiduMap from '@/components/Map/baiduMap/index.vue' const map = ref(null) const handleComplete = () => { // 渲染 点标记 map.value.renderMarker( [ { position: [116.39, 39.9], title: 'TA', content: 'CA', label: { content: 'LCA' } }, { position: [116.33, 39.5], title: 'TB', icon: '//vdata.amap.com/icons/b18/1/2.png' } ] ) } const handleMarkerClick = (position) => { map.value.openInfoWindow(position) } </script>关键点:
- 组件通过
ref="map"获取实例,随后调用map.value上的暴露方法; - 所有覆盖物渲染都应在
@complete(地图初始化完成)回调中执行,此时 BMapGL 实例已就绪; @marker-click事件会回传被点击覆盖物的position坐标数组,示例中直接用它打开对应的信息窗体。
三、Prop 属性详解
组件通过defineProps声明了 9 个属性,文档属性表与源码默认值一一对应:
| 名称 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| mid | 容器ID | String | 时间戳 |
| height | 容器高度 | Number | 800,单位px |
| apiKey | 地图Key | String | (必填,无默认值) |
| center | 地图中心点 | String | 自动定位 |
| plugins | 地图控件 | Array | 见下文控件列表 |
| viewMode | 效果:2D,3D | String | 3D |
| rotationAngle | 旋转角度 | Number | 60 |
| tiltAngle | 倾斜角度 | Number | 70 |
| zoom | 地图缩放比例 | Number | 12 |
| mapStyle | 地图样式:个性化地图 | String | 空 |
结合 index.vue 的源码,进一步说明几个关键属性的行为:
- apiKey:
required: true必填属性,组件加载脚本时会拼入ak=${props.apiKey},缺失则地图无法加载。 - mid:作为地图容器
container-${mid}的唯一 ID,默认取组件创建时间戳,保证同一页面多个地图实例互不冲突。 - center:类型实际为 Array(源码为
type: Array),格式为[经度, 纬度]。传入时组件直接以该点为中心初始化;不传则走浏览器定位(BMapGL.Geolocation().getCurrentPosition),定位失败时回退为根据已渲染覆盖物自动计算视野。 - viewMode:源码通过
validator限定取值只能是'2D'或'3D',传入其他值会触发 Vue 警告。 - zoom:默认 12,作为
centerAndZoom的缩放级别。 - mapStyle:传入个性化地图样式 ID(通过
setMapStyleV2应用),留空则使用默认底图样式。
四、地图控件(plugins)
组件默认挂载 4 个地图控件,对应源码 initControlPlugin 中的实现:
| 控件名称 | 说明 |
|---|---|
| BMap.ScaleControl | 比例尺 |
| BMap.ZoomControl | 缩放 |
| BMap.LocationControl | 定位 |
| BMap.NavigationControl3D | 3D控件 |
plugins属性默认值即为上述四个控件组成的数组,源码通过props.plugins.includes('BMap.xxx')逐个判断并addControl挂载。若传入空数组[],则地图只渲染底图、不挂任何控件;也可自定义子集,例如只需缩放与比例尺时传入['BMap.ScaleControl', 'BMap.ZoomControl']。
五、事件
组件通过defineEmits(['complete', 'markerClick'])声明了两个事件:
| 名称 | 说明 | 参数 | 参数类型 |
|---|---|---|---|
| complete | 当地图初始化完成时触发 | - | - |
| markerClick | 当点击了点覆盖物时触发 | position | Array |
其中complete是业务逻辑的"起跑线"——所有覆盖物渲染方法都应在该回调内调用;markerClick在点标记(Marker)、图标标记、3D 圆点标记、3D 图标标记上通过addEventListener('click', ...)注册后触发,回传的是该覆盖物原始position坐标数组。
六、覆盖物渲染方法(defineExpose 暴露的 10 个方法)
组件通过defineExpose将以下方法暴露给父组件调用:
| 名称 | 说明 | 参数 | 参数类型 |
|---|---|---|---|
| renderMarker | 渲染 点标记 | dataArr | Array |
| renderIconMarker | 渲染 图标标记 | dataArr | Array |
| render3DCircleMarker | 渲染 3D圆点标记 | dataArr | Array |
| render3DIconMarker | 渲染 3D图标标记 | dataArr | Array |
| renderPolyline | 渲染 线 | dataArr,option | Array,JSON |
| renderCircle | 渲染 圆 | position,radius,option | Array,Number,JSON |
| renderPolygon | 渲染 面 | dataArr,option | Array,JSON |
| renderInfoWindow | 渲染 信息窗体 | dataArr | Array |
| openInfoWindow | 打开 信息窗体 | position | Array |
| clearOverlay | 清理 覆盖物 | - | - |
从 index.vue 源码可梳理各方法的实现要点:
- renderMarker / renderIconMarker:遍历
dataArr创建BMapGL.Marker;图标版通过new BMapGL.Icon(d.img, new BMapGL.Size(imgWidth, imgHeight))设置自定义图标,未指定宽高时默认 40×40。 - render3DCircleMarker / render3DIconMarker:使用
BMapGL.Marker3D(point, height, options)构建立体标记,shape: 'BMAP_SHAPE_CIRCLE'为默认圆形,填充透明度固定 0.5;3D 图标版在 options 中传入 Icon 对象。 - renderPolyline / renderPolygon:先把
dataArr中的每个坐标转成BMapGL.Point加入内部点集合,再构造BMapGL.Polyline/BMapGL.Polygon覆盖物。 - renderCircle:参数为
(position, radius, option),半径未传时默认 500(米级比例按地图 API 语义处理)。 - renderInfoWindow:用
d.position作为 key 将BMapGL.InfoWindow缓存到内部对象baiduMapInfoWindowObj中,content文本数组通过join('<br>')连接,窗体宽度默认 250、高度默认 100。 - openInfoWindow:按
position从缓存中取出窗体实例,再openInfoWindow(infoWindow, new BMapGL.Point(...))打开。 - clearOverlay:直接调用
baiduMap.value.clearOverlays()清空全部覆盖物(不销毁地图)。
所有"渲染类"方法在末尾都会调用setFitView(),自动将视野调整到容纳全部覆盖物的范围。
七、方法参数 dataArr 结构
点标记
[{ "position": "坐标数组", "title": "鼠标滑过点标记时的文字提示" }]图标标记
[{ "position": "坐标数组", "title": "鼠标滑过点标记时的文字提示", "img": "图片地址", "imgWidth": "图片宽度,默认40", "imgHeight": "图片高度,默认40" }]3D圆点标记
[{ "position": "坐标数组", "height": "高度,默认8000", "size": "大小,默认50", "fillColor": "填充颜色,默认#006600" }]3D图标标记
[{ "position": "坐标数组", "height": "高度,默认8000", "size": "大小,默认50", "img": "图片地址", "imgWidth": "图片宽度,默认40", "imgHeight": "图片高度,默认40" }]线、面
[{ "position": "坐标数组" }]信息窗体
[{ "position": "坐标数组", "title": "标题", "content": "内容,文本数组,会以换行进行连接", "width": "窗体宽度", "height": "窗体高度" }]八、方法参数 option 结构
option 用于控制线、圆、面的样式,是可选参数(源码中option = {}兜底):
线、圆
{ "strokeColor": "边线颜色,默认blue", "strokeWeight": "边线宽度,默认2", "strokeOpacity": "边线透明度,默认0.5" }面
{ "strokeColor": "边线颜色,默认blue", "strokeWeight": "边线宽度,默认2", "strokeOpacity": "边线透明度,默认0.5", "fillColor": "填充颜色,默认blue", "fllOpacity": "填充透明度,默认0.5" }源码中样式通过option.strokeColor || 'blue'这类短路写法取默认值,因此只需按需覆盖需要的字段即可。注意源码中多边形填充透明度字段名为fllOpacity(文档保留该命名),填充透明度默认 0.5。
九、源码级实现原理剖析
1. 动态脚本加载与全局回调
组件在onMounted中调用init(),动态创建<script>标签注入页面头部:
script.src = `https://api.map.baidu.com/api?v=1.0&&type=webgl&ak=${props.apiKey}&callback=initMap`v=1.0与type=webgl指定加载 GL 版本 API;callback=initMap指向组件在window上注册的全局函数window.initMap,百度 API 加载完成后会自动回调它完成地图初始化。这也是必须在complete事件后再操作地图的原因——在此之前 BMapGL 尚未就绪。
2. 初始化与中心点决策逻辑
window.initMap内部依次完成:创建BMapGL.Map(container-mid)、开启滚轮缩放enableScrollWheelZoom(true)、按需setMapStyleV2应用个性化样式、挂载控件,然后依据center是否传入走两条路径——有center直接setFitView(point);无center则用BMapGL.Geolocation浏览器定位,定位失败时setFitView()无参调用,回退为按覆盖物视野自适应。两条路径最后都会emits('complete')。
3. 视野自适应与 3D 视角
setFitView是无参调用时的核心逻辑:通过getViewport(baiduMapPointArr)根据所有已加入点集合的坐标计算最优中心点,再centerAndZoom(point, props.zoom)定位。若viewMode === '3D',还会追加setHeading(props.rotationAngle)(旋转角,默认 60)与setTilt(props.tiltAngle)(倾斜角,默认 70),这就是组件能呈现 3D 立体视角的原因。
4. 生命周期清理
组件在onUnmounted中执行baiduMap.value.baseLayerAdded && baiduMap.value.destroy()销毁地图实例,避免页面切换后地图资源泄漏,这也是地图组件在路由跳转场景下的关键设计。
十、仓库中的完整实战示例
仓库在 snowy-admin-web/src/views/exm/map/baiduMap.vue 提供了可直接参考的完整示例页面,要点如下:
- 模板中仅一行组件:
<baidu-map ref="map" api-key="..." @complete="handleComplete" @marker-click="handleMarkerClick" />; handleComplete内以注释形式给出了点标记、图标标记、3D 圆点标记、3D 图标标记、多边形等各渲染方法的调用样例;- 实际生效的示例是信息窗体渲染:对两个坐标分别
renderInfoWindow,第二个窗体显式指定width: 300, height: 200; handleMarkerClick统一执行map.value.openInfoWindow(position),实现"点标记 → 弹信息窗体"的联动交互。
十一、使用注意事项
- Key 必填且需为 GL 版应用:
apiKey是required属性;由于组件加载type=webgl的 API,Key 必须在百度地图开放平台申请 GL 版浏览器端应用,否则地图无法加载。 - 渲染时机:所有
renderXxx方法务必在complete事件后调用,且应通过ref拿到组件实例(map.value)再调用,因为暴露方法挂在组件实例上。 - 3D 与 2D 的取舍:默认
viewMode='3D',若业务仅需平面地图,可显式传viewMode="2D",此时旋转、倾斜参数不生效。 - 多实例共存:同一页面渲染多个地图组件时,
mid默认按时间戳生成,天然隔离容器 ID;如需稳定 ID 可显式传入。 - 覆盖物清理:切换数据集或重新查询前,调用
clearOverlay()清空旧覆盖物,避免与新增覆盖物叠加。 - 信息窗体缓存:
openInfoWindow依赖renderInfoWindow预先缓存窗体对象,未渲染前调用不会有任何效果。
通过本文的属性和方法清单,配合 组件源码 与 示例页面,你可以在 Snowy 前端项目中快速构建基于百度地图 GL 的地图展示、标记与交互能力;若业务更倾向高德地图,可对照阅读仓库中 gaodeMap 组件文档,其 API 风格与本组件保持一致,迁移成本很低。
- 后端
- 前端
- 认证鉴权
- 应用安全
【免费下载链接】Snowy
💖国内首个国密前后分离快速开发平台💖《免费商用》,基于开源技术栈精心打造,融合Vue3+AntDesignVue4+Vite5+SpringBoot3+Mp+HuTool+Sa-Token。平台内置国密加解密功能,保障前后端数据传输安全;全面支持国产化环境,适配多种机型、中间件及数据库。特别推荐:插件提供工作流、多租户、多数据源、即时通讯等高级插件,灵活接入,让您的项目开发如虎添翼。
相关推荐
3分钟给 Win11 减负:免安装、改动全可撤销的 Windows 系统优化脚本
3分钟给 Win11 减负:免安装、改动全可撤销的 Windows 系统优化脚本 开始菜单推着推荐应用,锁屏弹着广告,还有一堆从没打开过的预装应用占着磁盘,这些
桌面应用CLIFlagsmith 前端特性开关集成实战:从环境配置到组件渲染与 MCP 管理
Flagsmith 前端特性开关集成实战:从环境配置到组件渲染与 MCP 管理 本指南基于 Flagsmith 仓库前端工程中沉淀的 Feature Flags
后端前端antd-mobile WaterMark 水印组件完全指南:从属性配置到 Canvas 渲染原理
antd mobile WaterMark 水印组件完全指南:从属性配置到 Canvas 渲染原理 水印(WaterMark)是 antd mobile 中用于
UI组件前端移动开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考