效果图
src/utils/gaode-map.ts
let _window = window as any;
// 2.0新版本
export function gaodeMap() {
return new Promise(function (resolve, reject) {
if (typeof _window.onLoadAMap === "function") {
resolve(_window.onLoadAMap);
} else {
_window.onLoadAMap = function () {
resolve(_window.onLoadAMap);
};
_window._AMapSecurityConfig = {
securityJsCode: "你的安全密钥",
};
var url = `https://webapi.amap.com/maps?v=2.0&key=你的key&callback=onLoadAMap&plugin=AMap.Geocoder,AMap.AutoComplete,AMap.PlaceSearch`;
var script = document.createElement("script");
script.src = url;
script.onerror = reject;
document.head.appendChild(script);
}
});
}
页面文件引入
<template>
<div id="mapContainer" style="width: 100%; height: 100%;"></div>
</template>
<script lang="ts">
import {
toRefs,
reactive,
onMounted,
defineComponent,
getCurrentInstance,
} from "vue";
import { gaodeMap } from "/@/utils/gaode-map";
let map: any = null;
const _window = window as any;
const projectList = [
{
id: 1,
title: "标题1",
aa: "aa",
bb: "bb",
cc: "cc",
dd: "dd",
longitude: "114.064919",
latitude: "22.538848",
},
{
id: 2,
title: "标题2",
aa: "aa",
bb: "bb",
cc: "cc",
dd: "dd",
longitude: "114.034919",
latitude: "22.518848",
},
{
id: 3,
title: "标题3",
aa: "aa",
bb: "bb",
cc: "cc",
dd: "dd",
longitude: "114.047919",
latitude: "22.510848",
},
];
export default defineComponent({
name: "BMap",
setup() {
// 页面加载时
onMounted(() => {
gaodeMap().then(() => {
initMap(); // 创建地图
});
});
const { proxy }: any = getCurrentInstance();
const data = reactive({
zoom: 12,
});
const initMap = async () => {
let mapCenter = [114.057923, 22.543648];
map = new AMap.Map("mapContainer", {
zoom: data.zoom,
center: mapCenter,
zooms: [4, 20], // 缩放区间
resizeEnable: true,
});
initProjectList();
mapEvent();
};
const mapEvent = () => {
// 缩放事件
map.on("zoomend", (e: any) => {});
// 拖拽事件
map.on("dragend", (e: any) => {});
};
const openInfoWindow = (item: any) => {
let currentPoint = [Number(item.longitude), Number(item.latitude)];
const geocoder = new AMap.Geocoder({});
geocoder.getAddress(currentPoint, (status: any, result: any) => {
if (status === "complete" && result.info === "OK") {
let currentAddress = result.regeocode.formattedAddress;
let dom = `<div class="map-info-window">
<div class="title">
<div>${item.title}</div>
<div class="close" onclick="$closeInfoWindow()">关闭</div>
</div>
<div class="content">
<div class="cell_left">
<img alt src="https://img1.baidu.com/it/u=2624835088,988907460&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500"/>
</div>
<div class="cell_right">
<ul>
<li>
<span class="tit">aaa:</span> ${item.aa}
</li>
<li>
<span class="tit">bbb:</span> ${item.bb}
</li>
<li>
<span class="tit">ccc:</span> ${item.cc}
</li>
<li>
<span class="tit">ddd:</span> ${item.dd}
</li>
<li>
<span class="tit">详细地址:</span> ${currentAddress}
</li>
</ul>
<div class="btn-link">
<button type="button" class="projectDetailBtn" data-item=${disposeJsonStr(
JSON.stringify(item)
)} onclick="$handleProjectDetailBtn()">项目详情</button>
</div>
</div>
</div>
</div>`;
let infoWindow = new AMap.InfoWindow({
isCustom: true, //使用自定义窗体
anchor: "bottom-center",
content: dom, //调用创建信息窗体的方法--信息窗体的内容
offset: new AMap.Pixel(0, -80),
});
infoWindow.open(map, currentPoint);
}
});
};
const initProjectList = async () => {
projectList.forEach(async (item: any) => {
var circle = new AMap.Circle({
//创建一个圆
center: new AMap.LngLat(item.longitude, item.latitude),
radius: 1000, //半径
strokeColor: "red", //边线颜色。
fillColor: "red", //填充颜色。当参数为空时,圆形将没有填充效果。
strokeWeight: 3, //边线的宽度,以像素为单位。
strokeOpacity: 1, //边线透明度,取值范围0 - 1。
fillOpacity: 0.6, //填充的透明度,取值范围0 - 1。
strokeStyle: "solid", //边线的样式,solid或dashed。
});
map.add(circle);
circle.on("click", function (event: any) {
openInfoWindow(item);
});
});
};
_window.$closeInfoWindow = function closeInfoWindow() {
map.closeInfoWindow();
};
_window.$handleProjectDetailBtn = function handleProjectDetailBtn() {
const dom = document.querySelector(".projectDetailBtn") as HTMLElement;
let item: any = dom.getAttribute("data-item");
item = JSON.parse(item);
console.log("item---", item);
};
// JS去除JSON字符串各种空格、换行符
function disposeJsonStr(str: string) {
return str.replace(/\r\n/g, "").replace(/\n/g, "").replace(/\s+/g, "");
}
return {
...toRefs(data),
};
},
});
</script>
<style scoped lang="scss">
::v-deep(.map-info-window) {
position: relative;
border: 1px solid #6DCFF6;
min-width: 200px;
background: #0F2858;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.3);
border-radius: 5px;
color: #000;
&:before,
&:after {
display: block;
content: '';
width: 0;
height: 0;
position: absolute;
left: 50%;
// transform: translateX(-50%);
}
&:before {
margin-left: -6px;
bottom: -20px;
z-index: 999;
border-top: 20px solid #0F2858;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
}
&:after {
margin-left: -8px;
bottom: -22px;
z-index: 998;
border-top: 22px solid #6DCFF6;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
}
.title {
display: flex;
justify-content: space-between;
align-items: center;
color: white;
max-width: 600px;
padding: 8px 15px;
border-bottom: 1px solid #CCC;
font-size: 14px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
.close {
height: 20px;
line-height: 20px;
font-size: 12px;
border: 1px solid #fff;
padding: 0 8px;
border-radius: 4px;
&:hover {
cursor: pointer;
color: #6dcff6;
border: 1px solid #6dcff6;
}
}
}
.content {
padding: 8px 15px;
font-size: 12px;
display: flex;
justify-content: space-around;
align-items: center;
height: 190px;
.cell_left {
width: 170px;
height: 100%;
margin: -2px 20px 0 4px;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #CCC;
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.3);
overflow: hidden;
>img {
width: 155px;
height: 155px;
object-fit: cover;
}
}
.cell_right {
position: relative;
height: 100%;
>ul {
>li {
width: 200px;
padding: 3px 0;
font-size: 12px;
color: #fff;
>span {
color: #fff;
padding-right: 5px;
}
}
}
.btn-link {
position: absolute;
right: 0px;
bottom: 0px;
padding: 0px;
cursor: pointer;
display: flex;
justify-content: flex-end;
>button {
border: 1px solid #CCC;
font-size: 12px;
background: transparent;
color: #fff;
line-height: 12px;
padding: 5px 10px;
border-radius: 3px;
cursor: pointer;
&:hover {
border: 1px solid #6dcff6;
color: #6dcff6;
}
}
}
}
}
}
</style>