参考博主:vue3 Element plus 百度地图封装( 搜索定位功能,拖拽回显功能)_vue3 pc端实现定位回显位置信息-CSDN博客
运行环境:vue3+Ant Design
1,申请百度地图ak
网址:百度地图-百万开发者首选的地图服务商,提供专属的行业解决方案
登录/注册后点击右上角控制台,点击左侧【应用管理】下的【我的应用】【创建应用】申请ak
2,index.html内引入
<script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&ak=申请的ak值&s=1"></script>
3,画地图
<template>
<!-- 这个是我这个框架里封装好的弹窗组件 -->
<BasicModal
width="1200px"
v-bind="$attrs"
:defaultFullscreen="true"
:canFullscreen="false"
@register="registerModal"
title="定位"
@ok="handleSubmit"
>
<!-- ----地图相关--- -->
<!-- 表单用于搜索 -->
<a-form class="formdom">
<a-form-item label="详细地址">
<a-auto-complete
v-model:value="mapData.address"
placeholder="请输入详细地址"
:backfill="true"
:options="optionsAll"
@search="querySearch"
@select="handleSelect"
>
<template #option="item">
<div>
<div>{{ item.title }}</div>
<span style="font-size: 12px; color: #b4b4b4">{{ item.address }}</span>
</div>
</template>
</a-auto-complete>
</a-form-item>
<!-- 显示经纬度 -->
<a-form-item label="经纬度">
<a-input v-model:value="mapData.point" :disabled="true" />
</a-form-item>
</a-form>
<!-- 画的地图 -->
<div id="map" style="width: 100%; height: 100%"></div>
</BasicModal>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal'; //框架自带的弹窗组件可忽略
import { SearchOutlined } from '@ant-design/icons-vue'; //我用的是Ant Design组件库,这个是引入搜索图标
export default defineComponent({
name: 'AppModal',
components: {
BasicModal, //可忽略
},
emits: ['success'],
setup(props, { emit }) {
const isUpdate = ref(true); //可忽略
// 初始经度,纬度
const lat = ref(36.67411054692821);
const lng = ref(117.10358591219932);
// 搜索框下拉选项
const optionsAll = ref([]);
// 初始化地图
let Map = null;
// 初始图标
let mk = null;
// 地图缩放级别
let zoom = 12;
// 先定义一个全局变量后面用
const BMap = window.BMap;
// 坐标信息
const mapData = ref({
address: '', //详细地址
point: '', //经纬度
lat: '', //经度
lng: '', //纬度
});
// 初始函数
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
//我这一行引入的都是BasicModal弹窗组件封装好的与地图无关
// 把值都清空
mapData.value.address = '';
mapData.value.point = '';
mapData.value.lat = '';
mapData.value.lng = '';
if (data.isUpdate) {
// 编辑-因为我这个是弹窗打开地图,可能是编辑可能是添加,也就坐标和地址回显
lat.value = data.records.lat;
lng.value = data.records.lng;
mapData.value.lat = data.records.lat;
mapData.value.lng = data.records.lng;
mapData.value.address = data.records.address;
mapData.value.point = data.records.lng + ',' + data.records.lat;
}
// 弹窗初始化
setModalProps({ confirmLoading: false }); //与地图无关
isUpdate.value = !!data?.isUpdate; //与地图无关
//初始化地图 禁用地图默认点击弹框
Map = new BMap.Map('map', { enableMapClick: false });
var point = new BMap.Point(lng.value, lat.value);
// 初始化 地图经纬度 层级12代表缩放zoom
Map.centerAndZoom(point, zoom);
Map.enableScrollWheelZoom(true); //滚动缩放
//创建一个图像标注实例 启用拖拽 默认为false
mk = new BMap.Marker(point, { enableDragging: true });
// 图标图片尺寸设置
mk.z.Bj.size.height = 100;
mk.z.Bj.size.width = 100;
Map.addOverlay(mk); //将覆盖物添加到地图中
// 地图拖动事件
Map.addEventListener('dragend', function (e) {
Map.panTo(e.point); //将地图的中心点更改为给定的点
getAddrByPoint(e.point); //拖拽结束后调用逆地址解析函数,e.point为拖拽后的地理坐标
});
// 图标拖动事件
mk.addEventListener('dragend', function (e) {
getAddrByPoint(e.point); //拖拽结束后调用逆地址解析函数,e.point为拖拽后的地理坐标
});
});
// 逆解析函数
async function getAddrByPoint(point) {
var geco = new BMap.Geocoder();
geco.getLocation(point, function (res) {
mapData.value = {
address: res.address,
point: point.lng + ' , ' + point.lat,
lat: point.lat,
lng: point.lng,
};
mk.setPosition(point); //重新设置标注的地理坐标
// Map.panTo(point); //将地图的中心点更改为给定的点
});
}
// 搜索函数
const querySearch = (str) => {
var options = {
//检索完成后的回调函数
onSearchComplete: function (res) {
var arr = [];
if (local.getStatus() == BMAP_STATUS_SUCCESS) {
for (var i = 0; i < res.getCurrentNumPois(); i++) {
arr.push(res.getPoi(i));
}
}
//拿到数据之后回显给搜索框的下拉框
optionsAll.value = arr;
optionsAll.value.forEach((item) => {
item.value = item.address;
});
},
};
var local = new BMap.LocalSearch(Map, options);
local.search(str);
};
// 搜索框的下拉框,选中某项会触发的-选择函数
const handleSelect = (val, options) => {
// 保存当前数据
mapData.value = {
address: options.address,
point: options.point.lng + ' , ' + options.point.lat,
lat: options.point.lat,
lng: options.point.lng,
};
mk.setPosition(options.point); //重新设置标注的地理坐标
Map.panTo(options.point); //将地图的中心点更改为给定的点
};
// 弹窗保存--把值传回去
async function handleSubmit() {
const latlng = {
lat: mapData.value.lat,
lng: mapData.value.lng,
};
emit('success', {
positonStr: mapData.value.address,
latlng: latlng,
});
closeModal();
}
return {
registerModal,
handleSubmit,
handleSelect,
querySearch,
mapData,
optionsAll,
SearchOutlined,
};
},
});
</script>
<style scoped lang="scss">
.formdom {
position: absolute;
top: 0;
background-color: #fff;
z-index: 10;
display: flex;
justify-content: space-evenly;
align-items: center;
width: 100%;
::v-deep(.ant-row) {
width: 30%;
}
}
</style>
4,可能报错,我在本地跑的时候是正常的,但是放到线上之后就有问题了"报错BMap is not defined"并且地图是空白的,细心的话在最开始还会有下面这张图上的错误,查了一下解决办法就是在index.html引入的时候在末尾加上&s=1因为我最开始是http为了以防万一我也改成https了