最近在赶新的项目,用了百度地图去开发,涉及地图的操作太多,目前就摸清标题所写的功能,趁今晚有空记录下来先,因为在开发的的过程找了许多帖子,因为我基于Vue3去开发的,发现很多都是基于vue2开发的,Vue3的比较少,改成Vue3时改的吃力或者修改后运行不了,所以折腾一了段时间。所以把目前完成的代码发出来,供大家参考,涉及后端的接口的数据,我也模拟了一些数据在上面了,可以开箱即用。
效果图:
一、百度地图在vue3中的引入
1.首先在百度地图开发中心中申请ak(不多介绍)
2.两种引入方式:第一种在 index.html 中直接引入;第二种使用导包。(我使用的是index.html引入)
百度地图logo和信息去掉屏蔽,index.html加:
<style> .BMap_cpyCtrl, .anchorBL { display: none; } </style>搜索框的功能是用element-plus的el-autocomplete的,所以用别的,小伙伴自行修改。效果如图:
全部代码:
<template> <div class="boxmain"> <div class="box"> <div class="elInput"> <el-autocomplete popper-class="autoAddressClass" v-model="searchResults" :fetch-suggestions="searchLocation" :trigger-on-focus="false" placeholder="请输入详细地址" @select="handleSelect" clearable> <template #default="{ item }"> <div class="autoAddressClass_item"> <ElIcon :size="20" color="balck"> <Search /> </ElIcon> <div> <div class="title">{{ item.title }}</div> <span class="address ellipsis">{{ item.address }}</span> </div> </div> </template> </el-autocomplete> </div> <div class="bbox" id="map"></div> </div> </div> </template> <script setup> import { onMounted, onBeforeUnmount, ref } from 'vue'; import { ElMessage } from 'element-plus'; import { devicesOnline } from '../../utils/api.js'; onMounted(() => { // 调用获取用户位置的函数 getLocation(); }); onBeforeUnmount(() => { // 在这里可以添加一些清理工作 }); const map = ref(); const addName = ref(""); const getLocation = () => { // if (navigator.geolocation) {//进入页面就自动获取定位,有项目需要,暂时屏蔽,先写死先 // navigator.geolocation.getCurrentPosition( // position => { // const longitude = position.coords.longitude; // const latitude = position.coords.latitude; // initMap(longitude, latitude); // _devicesOnline(); // }, // error => { // ElMessage.error('无法获取您的位置信息。'); // } // ); // } else { // ElMessage.error('浏览器不支持地理位置获取。'); // } initMap(113.456941, 23.161843); _devicesOnline();//这是我获取坐标点接口,我模拟了一些数据在下面 }; const initMap = (longitude, latitude) => { map.value = new BMap.Map('map'); const point = new BMap.Point(longitude, latitude); const icons = new BMap.Symbol(BMap_Symbol_SHAPE_POINT, {//自定义图标 // 坐标颜色设置 scale: 0, fillColor: 'rgb(72, 153, 188)', // 填充颜色 fillOpacity: 1, // 填充透明度 strokeColor: 'rgba(0,5,0,0)' }); const marker = new BMap.Marker(point, { icon: icons }); map.value.centerAndZoom(point, 14); // map.value.disableScrollWheelZoom(true); //禁用地图的鼠标滚轮缩放功能。设置为 true 表示禁用,如果设置为 false 则启用。 map.value.enableScrollWheelZoom();//用于启用地图的鼠标滚轮缩放功能。一般情况下,如果之前使用了 disableScrollWheelZoom 来禁用了滚轮缩放,之后可以使用 enableScrollWheelZoom 来重新启用。 map.value.addOverlay(marker);// 添加地图标注 // marker.setAnimation(BMAP_ANIMATION_BOUNCE); //定位坐标跳动的动画 openInfosub(marker, point); // 添加缩放控件 const navigationControl = new BMap.NavigationControl(); map.value.addControl(navigationControl); // 添加定位控件 const geolocationControl = new BMap.GeolocationControl({ anchor: BMAP_ANCHOR_BOTTOM_RIGHT, showAddressBar: true, //是否显示定位信息面板 enableAutoLocation : true, //首次是否进行自动定位 offset: new BMap.Size(6,6)//偏移距离 }); map.value.addControl(geolocationControl); // 添加比例尺控件 const scaleControl = new BMap.ScaleControl(); map.value.addControl(scaleControl); // 地图卫星切换 const mapTypeControl = new BMap.MapTypeControl({ mapTypes: [BMAP_NORMAL_MAP, BMAP_SATELLITE_MAP] }); map.value.addControl(mapTypeControl); // 点击标注监听事件 marker.addEventListener('click', function (e) { console.log(e); }); }; const openInfosub = (marker, point) => { const opts = { width: 250, height: 100, title: '信息窗口', enableAutoPan: false }; const infoWindow = new BMap.InfoWindow('世界你好', opts); // map.value.openInfoWindow(infoWindow, point);//这个是进入界面就直接出弹窗,点击事件没写,可参考下面坐标集合的另外一种触发点击方法 }; const showMarkers = (coordinates) => {//图像标注 console.log(coordinates, 'coordinates'); coordinates.forEach(coord => { const points = new BMap.Point(coord.longitude, coord.latitude); const markers = new BMap.Marker(points); map.value.addOverlay(markers); openInfoWins(markers, coord, points); }); }; const openInfoWins = (markers, data, points) => { const opts = { width: 250, height: 100, padding: 2, enableAutoPan: true }; let { latitude, longitude, name } = data; const sContent = ` <div style="margin-top:-15px;"><p>设备名字: ${name}</p><p>GPS经度: ${longitude}</p> <p>GPS纬度: ${latitude}</p> </div> `; const infoWindow = new BMap.InfoWindow(sContent, opts); markers.addEventListener('click', function (e) { openInfo(infoWindow, points, e); }); }; const openInfo = (infoWindow, points, e) => { map.value.openInfoWindow(infoWindow, points); //开启信息窗口 }; const _devicesOnline = async () => {//条件查询在线设备 const data = await devicesOnline();//获取坐标集合的接口 let datalist = [{ "id": 31, "name": "设备31", "longitude": 113.496941, "latitude": 23.129843 }, { "id": 30, "name": "设备30", "longitude": 113.468941, "latitude": 23.199843 }, { "id": 29, "name": "设备29", "longitude": 113.416941, "latitude": 23.139843 }, { "id": 28, "name": "设备28", "longitude": 113.495941, "latitude": 23.179843 }] console.log(data, '在线设备'); if (data.success == 1) { // showMarkers(data.data.records); showMarkers(datalist);//给你们模拟的数据 } else { ElMessage.error(data.message ?? '获取设备失败'); } }; const searchResults = ref([]); const searchLocation = async (str, cb) => {// 使用百度地图的地点搜索服务 console.log(str, 'str'); const local = new BMap.LocalSearch(map.value, { onSearchComplete: function (res) { var arr = []; if (local.getStatus() == BMAP_STATUS_SUCCESS) { for (var i = 0; i < res.getCurrentNumPois(); i++) { arr.push(res.getPoi(i)); } cb(arr) } else { ElMessage.error('未找到相关地点,请尝试其他关键字。'); } } }); local.search(str); console.log(searchResults.value); }; const handleSelect = (item) => {//点击搜索的点位并地图跳转到该坐标 console.log(item) searchResults.value = item.address const point = new BMap.Point(item.point.lng, item.point.lat); map.value.centerAndZoom(point, 14); // var marker = new BMap.Marker(point); // 创建标注 // map.value.addOverlay(marker); // 将标注添加到地图中 // marker.setAnimation(BMAP_ANIMATION_BOUNCE); //坐标跳动的动画 } </script> <style scoped> .boxmain { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; overflow: auto; box-shadow: 0 0 1.5vw #1f69b9b9 inset; background: linear-gradient(#33cdfa, #33cdfa) left top, linear-gradient(#33cdfa, #33cdfa) left top, linear-gradient(#33cdfa, #33cdfa) right top, linear-gradient(#33cdfa, #33cdfa) right top, linear-gradient(#33cdfa, #33cdfa) left bottom, linear-gradient(#33cdfa, #33cdfa) left bottom, linear-gradient(#33cdfa, #33cdfa) right bottom, linear-gradient(#33cdfa, #33cdfa) right bottom; background-repeat: no-repeat; background-size: 0.1vw 1.5vw, 1.5vw 0.1vw; } .box { width: 98%; height: 96%; } .bbox { width: 100%; height: 100%; } .elInput { position: absolute; z-index: 2; margin-left: 65px; margin-top: 5px; width: 200px; } .autoAddressClass li .title { line-height: 30px; text-overflow: ellipsis; overflow: hidden; } .autoAddressClass li .address { line-height: 1; font-size: 12px; color: #b4b4b4; margin-bottom: 5px; } .autoAddressClass li .autoAddressClass_item { overflow: hidden; display: flex; align-items: center; } .autoAddressClass li .autoAddressClass_item .el-icon { margin-right: 20px; } </style>另外别的菜单还有电子围栏功能还是个半成品,等完成后有空再发吧,现有的功能只有这样。