一、初始化高德
<template>
<div id="container"></div>
</template>
import remoteLoad from "@/utils/remoteLoad";
export default {
props: ["positions"],
data() {
return {
map: null,
Amap: null,
};
},
mounted() {
this.$nextTick(() => {
if (window.AMap) {
this.initMap();
// 未载入高德地图API,则先载入API再初始化
} else {
const MapKey = "e0b2b795bcd2a0f79f0de02a7ff26385";
const securityJsCode = "d056558cf29ed70c4b39903430ccb130";
window._AMapSecurityConfig = { securityJsCode };
remoteLoad(`https://webapi.amap.com/maps?v=2.0&key=${MapKey}`)
.then(() => {
remoteLoad("https://webapi.amap.com/ui/1.1/main.js").then(
this.initMap
);
})
.catch((e) => {
console.log(e);
});
}
});
},
methods: {
initMap() {
const AMap = (this.AMap = window.AMap);
this.map = new AMap.Map("container", {
resizeEnable: true,
center: [120.19403, 30.23546],
zoom: 16,
});
},
// 添加标记点
initPosition(obj = this, positions = this.positions) {
const _this = this;
const AMap = this.AMap;
// 创建 AMap.LabelsLayer 图层
const layer = new AMap.LabelsLayer({
zooms: [3, 20],
zIndex: 2000,
collision: false,
});
// 将图层添加到地图
_this.map.add(layer);
const markers = [];
const icon = {
type: "image",
// 自定义点标记
image,
size: [22, 41],
anchor: "bottom-center",
};
positions.forEach((position) => {
const curData = {
position,
icon,
};
const labelMarker = new AMap.LabelMarker(curData);
markers.push(labelMarker);
// 给marker绑定事件
labelMarker.on("click", function (e) {
const position = e.data.data && e.data.data.position;
// 传入经纬度,设置地图中心点
const centerP = new AMap.LngLat(...position);
_this.map.setZoomAndCenter(16, centerP);
setTimeout(() => {
_this.$emit("iconClick", centerP);
}, 0);
});
});
// 一次性将海量点添加到图层
layer.add(markers);
},
// 添加信息窗体
openContent(position, refInfoContent) {
const AMap = this.AMap;
!this.infoWindow &&
(this.infoWindow = new AMap.InfoWindow({
isCustom: true, //使用自定义窗体
content: refInfoContent, //传入 dom 对象,或者 html 字符串
offset: new AMap.Pixel(0, -45),
}));
this.infoWindow.open(this.map, position);
},
},
};
二、remoteLoad.js 文件
export default function remoteLoad(url, hasCallback) {
return createScript(url);
/**
* 创建script
* @param url
* @returns {Promise}
*/
function createScript(url) {
const scriptElement = document.createElement("script");
document.body.appendChild(scriptElement);
const promise = new Promise((resolve, reject) => {
scriptElement.addEventListener(
"load",
(e) => {
removeScript(scriptElement);
if (!hasCallback) {
resolve(e);
}
},
false
);
scriptElement.addEventListener(
"error",
(e) => {
removeScript(scriptElement);
reject(e);
},
false
);
if (hasCallback) {
window.____callback____ = function () {
resolve();
window.____callback____ = null;
};
}
});
if (hasCallback) {
url += "&callback=____callback____";
}
scriptElement.src = url;
return promise;
}
/**
* 移除script标签
* @param scriptElement script dom
*/
function removeScript(scriptElement) {
document.body.removeChild(scriptElement);
}
}
三、使用组件
<div class="detail_map">
<digmapVue ref="dMap" @iconClick="iconClick" :positions="positions" />
// 信息窗体
<div
ref="JinfoContent"
class="centerDialog mapContent"
v-if="dialogVisible"
>
<p class="close" @click="dialogClose"></p>
<h1>{{ content.name }}</h1>
<div class="address">
{{ content.address }}
</div>
<hr />
<div class="cont">
<div class="taps" v-for="item in content.content" :key="item.name">
<div class="num">{{ item.num }}</div>
<div class="name">{{ item.name }}</div>
</div>
</div>
</div>
</div>
import digmapVue from "@/components/aMap/digmap.vue";
export default {
name: "DialogComponent",
components: {
digmapVue,
},
data() {
return {
dialogVisible: false,
dlLayer: {},
content: {
name: "标题",
address: "地址:防痘小区",
content: [
{
name: "左边",
num: "888人",
},
{
name: "右边",
num: "888个",
},
],
},
};
},
props: ["title"],
mounted() {
this.$nextTick(() => {
this.$refs.dMap.initPosition(this.dlLayer, [
[120.18877, 30.23849],
[120.19403, 30.23546],
]);
});
},
methods: {
iconClick(position) {
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs.dMap.openContent(position, this.$refs.JinfoContent);
});
},
},
};
信息窗体样式
.centerDialog {
text-align: center;
&:not(.mapContent) {
position: absolute;
z-index: 1500;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
width: 210px;
height: 135px;
padding: 10px 10px 17px 10px;
background: url("@/assets/map/tips.png") no-repeat;
background-size: 210px 135px;
font-family: "PuHuiTi";
font-weight: 500;
font-size: 16px;
color: #e0ecff;
position: relative;
span {
font-weight: 400;
font-size: 14px;
// color: #6b9ceb;
}
.close {
position: absolute;
top: -18px;
right: -24px;
width: 68px;
height: 56px;
cursor: pointer;
background: url("~@/assets/close.svg") center center/16px 16px no-repeat;
}
h1 {
font-weight: 500;
font-size: 16px;
color: #fff;
}
.address {
font-weight: 400;
font-size: 12px;
color: #fff;
opacity: 0.5;
padding-bottom: 11px;
}
hr {
background: #213248;
}
.cont {
display: flex;
justify-content: space-between;
.taps {
padding-top: 10px;
width: 50%;
color: #fff;
.num {
font-size: 20px;
font-weight: 700;
letter-spacing: 0;
}
.name {
font-weight: 400;
font-size: 12px;
opacity: 0.5;
}
}
}
}