1. 使用前提
- 到百度地图开发平台获取
应用AK
,设置Referer白名单
2. 在项目中引入地图
<script type="text/javascript" src="https://api.map.baidu.com/api?v=3.0&ak=应用AK"></script>
3. 创建组件
<template>
<div class="map"></div>
</template>
<script setup lang="ts">
import { defineExpose, defineEmits, ref, reactive } from 'vue'
// 地图实例
const map = ref()
// 经纬度
let point = reactive({})
/**
* 初始化地图实例,添加地图点击事件
* @param {object} pointObj 经纬度
* @param {boolean} scrollWheelZoom 是否需要滚轮缩放
* @return {void}
*/
const createdMap = (pointObj: any, scrollWheelZoom = true) => {
map.value = new BMap.Map(document.querySelector('.map'));
point = new BMap.Point(pointObj.lng, pointObj.lat);
// 缩放倍数其实也可以通过参数传进来
map.value.centerAndZoom(point, 15);
// 鼠标滚轮是否可以缩放
if (scrollWheelZoom) {
map.value.enableScrollWheelZoom(true);
}
// 点击地图
map.value.addEventListener('click', function (e: any) {
emit('clickMap', e)
});
}
/**
* 添加标注(此处也应该把经纬度作为参数传递进来比较好)
* @return {void}
*/
const createdMarker = () => {
let marker = new BMap.Marker(point);
map.value.addOverlay(marker);
}
/**
*设置窗口信息
* @param {object} opts 窗口标题,宽高等
* @param {string} Dom 自定义DOM
* @return {void}
*/
const setInfoWindow = (opts: any, Dom: any) => {
var infoWindow = new BMap.InfoWindow(Dom, opts);
map.value.openInfoWindow(infoWindow, map.value.getCenter());
}
/**
*获取坐标的地址描述
* @param {object} point 经纬度
* @return {Promise}
*/
const getLocation = (point: any) => {
return new Promise((res, reg) => {
let pointObj = new BMap.Point(point.lng, point.lat)
var myGeo = new BMap.Geocoder();
myGeo.getLocation(pointObj, function (result: any) {
if (result) {
res(result)
} else {
reg('...')
}
});
})
}
/**
*获取经纬度
* @param {string} city 城市
* @param {string} place 地点
* @return {Promise}
*/
const getPoint = (city: any, place: any) => {
return new Promise((res, reg) => {
var myGeo = new BMap.Geocoder();
myGeo.getPoint(place, function (point: any) {
if (point) {
res(point)
} else {
reg("找不到")
}
}, city)
})
}
//
const emit = defineEmits(['clickMap'])
defineExpose({
createdMap,
createdMarker,
getLocation,
getPoint,
setInfoWindow
})
</script>
<style scoped>
.map {
width: 100%;
height: 100%;
}
</style>
<style scoped lang="less">
/deep/.BMap_cpyCtrl,
/deep/ .anchorBL {
display: none !important;
}
</style>
3. 在页面中使用
<template>
<div class="map_box_my">
<div class="dd">
<a-cascader style="width:200px" v-model:value="city" :options="arr" placeholder="选择城市" />
<a-input style="width:200px" v-model:value="place" placeholder="输入地点" />
<a-button type="primary" @click="onSearch">搜索</a-button>
</div>
<bMapCom ref="childRef" @clickMap="clickMap"></bMapCom>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { message } from 'ant-design-vue';
// 省市数据
import arr from './index.js'
// 地图组件
import bMapCom from '@/components/bMapCom/index.vue'
const childRef = ref(null)
const city = ref()
const place = ref()
// 初始化
onMounted(async () => {
let point = {
lng: '116.404',
lat: '39.915'
}
// 通过经纬度获取地点的详细信息
const data = await childRef.value.getLocation(point)
let dom = `
<h1>
${data.surroundingPois[0] ? data.surroundingPois[0].title : place.value}
</h1>
<div>
${data.address}${data.surroundingPois[0] ? '-' + data.surroundingPois[0].address : ''}
</div>
`
// 创建地图
childRef.value.createdMap(point)
// 添加标注
childRef.value.createdMarker()
// 设置窗口信息
childRef.value.setInfoWindow({}, dom)
})
// 点击地图
const clickMap = async (e: any) => {
// 通过经纬度获取地点的详细信息
const data = await childRef.value.getLocation(e.point)
message.success(`经度:${e.point.lng}--纬度:${e.point.lat}--地点:${data.address}`);
}
// 输入地点搜索
const onSearch = async () => {
if (city.value && city.value.length && place.value) {
try {
// 根据搜索地点获取经纬度
const res = await childRef.value.getPoint(city.value[city.value.length - 1], place.value)
// 通过经纬度获取地点的详细信息
const data = await childRef.value.getLocation(res)
let dom = `
<h1>
${data.surroundingPois[0] ? data.surroundingPois[0].title : place.value}
</h1>
<div>
${data.address}${data.surroundingPois[0] ? '-' + data.surroundingPois[0].address : ''}
</div>
`;
// 创建地图
childRef.value.createdMap(res)
// 添加标注
childRef.value.createdMarker()
// 设置窗口信息
childRef.value.setInfoWindow({}, dom)
} catch (err) {
console.log(err)
}
} else {
message.error('城市和地点都不能为空,否则搜索不到');
}
}
</script>
<style lang="less" scoped>
.map_box_my {
width: 100vw;
height: 100vh;
position: relative;
}
.dd {
position: absolute;
z-index: 999;
left: 20px;
top: 20px;
display: flex;
padding: 10px;
background: #fff;
border-radius: 5px;
box-shadow: 0 0 30px 1px #999
}
</style>
4. 图



5. 后续