环境:vue 2.9.6
本来看着vue集成了相关的高德地图,本以为就可以很方便的调用,结果发现功能很不齐全,本次涉及到的基本maker操作都没有,无奈只好引入原生js,遇到了很多坑记录下:
代码现行:
<script src="http://webapi.amap.com/maps?v=1.3&key=xxx"></script>
<script src="http://webapi.amap.com/ui/1.0/main.js"></script>
二话不说先在index.html中直接引入高德相关
写成组件化():
<!--
描述:拖放地图组件,默认尺寸是 500 * 300
接收属性参数:
lat: 纬度
lng: 经度
自定义事件:
drag: 拖放完成事件
示例:
<mapDrag @drag="dragMap" lat="22.574405" lng="114.095388"></mapDrag>
-->
<template>
<div class="m-map">
<div id="js-container" class="map" >正在加载数据 ...</div>
<img style=" position:relative;top: -55px;left: 5px;width: 45px;" src="../../assets/images/jw_logo.png" >
</div>
</template>
<script>
import { MapKey, BuildingPng} from '../config/config'
export default {
props: ['lat', 'lng'],
data () {
return {
cluster:null,
dragStatus: false,
AMapUI: null,
AMap: null,
marker:null,
map:null,
map_lng:null,
map_lat:null,
geocoder:null,
strLen:0,
buildingList:[],
switchBoo:true,
switchWatch:true,
markers:[]
}
},
mounted(){
},
watch: {
markers(){
if (this.switchWatch){
this.addCluster(1);
this.switchWatch = false;
}
}
},
methods: {
initMapMaker(){
this.buildingList = [];
let that = this;
$.ajax({
type: "get",
url: 获取请求所有需要创建的makers,
dataType: "json",
success: function(data) {
if (data.code === 200){
that.buildingList = data.buildings;
that.buildingList.forEach((obj)=>{
that.addMarker(obj.longitude, obj.latitude, obj.name, obj.email, 1, obj.uniqueKey);
})
}
},
});
},
clear(){
this.placeSearch.clear();
},
async initInfo(){
this.initMap();
},
//获取并展示当前城市信息
logMapinfo(){
this.map.getCity( function(info){
return info.city;
});
},
//计算字符串长度
strLength(str){
let realLength = 0, len = str.length, charCode = -1;
for (let i = 0; i < len; i++) {
charCode = str.charCodeAt(i);
if (charCode >= 0 && charCode <= 128)
realLength += 1;
else
realLength += 2;
}
return realLength;
},
//设置视角
setView(lng, lat){
this.map.setZoomAndCenter(16,[lng, lat]);
},
// 创建标记
addMarker(lng, lat, mapName, email, type, uniqueKey) {
if (email !== '' && email !== null ){
let shifting = 0;
let span = '<span class="map-email" style="margin-top: 6px">'+email+'</span>';
//若名称大于邮箱展示,则重新设置偏移
if (this.strLength(mapName) > this.strLength(email)){
shifting =-5 * (this.strLength(mapName) - 16) + 5;
}else {
if (this.strLength(email) < 16){
shifting = -this.strLength(email) * 10 + 140;
}
}
if (lng !== null && lat !== null){
if (type === 1){
this.marker = new AMap.Marker({
icon: BuildingPng,
position: [lng,lat],
offset: new AMap.Pixel(-13, -30),
label:{
content: '<div class="map-name"><span>'+mapName+'</span>'+span+'</div>',
offset: new AMap.Pixel(-55 + shifting, 55)
},
extData:uniqueKey
});
}else {
this.marker = new AMap.Marker({
icon: BuildingPng,
position: [lng,lat],
offset: new AMap.Pixel(-13, -30),
extData:uniqueKey
});
}
this.markers.push(this.marker);
// this.marker.setMap(this.map);
let that = this;
new AMap.event.addListener(this.marker, 'click', function(e) {
//得到的数据
that.$store.commit('setMapShow_uniqueKey', JSON.parse(JSON.stringify(e.target.getExtData())));
const { href } = that.$router.resolve({ name:'MapShow'});
window.open(href, '_blank', )
});
}
}
},
// 清除 marker
clearMarker() {
if (this.marker) {
this.marker.setMap(null);
this.marker = null;
}
},
//鼠标单击事件获取坐标
showInfoClick(e){
this.map_lng = e.lnglat.getLng();
this.map_lat = e.lnglat.getLat();
},
// 搜索
handleSearch () {
this.setView(104.071078, 30.545154);
},
//设置建筑
setBuildingList(val){
if (val === ''){
this.map.setZoomAndCenter(16,[104.065861, 30.657401]);
}else {
this.buildingList = val;
}
},
//聚合makers
addCluster(tag) {
if (this.cluster) {
this.cluster.setMap(null);
} else if (tag === 1) {//自定义图标
var sts = [{
url: require('../images/TogetherPng.png'),
size: new AMap.Size(43, 50),
offset: new AMap.Pixel(-13, -30),
imageOffset:new AMap.Pixel(0, 0),
textColor:'#ffffff',
textSize: 20
},
{
url: require('../images/TogetherPng.png'),
size: new AMap.Size(43, 50),
offset: new AMap.Pixel(-13, -30),
imageOffset:new AMap.Pixel(0, 0),
textColor:'#ffffff',
textSize: 20
},
{
url: require('../images/TogetherPng.png'),
size: new AMap.Size(43, 50),
offset: new AMap.Pixel(-13, -30),
imageOffset:new AMap.Pixel(0, 0),
textColor:'#ffffff',
textSize: 20
},
{
url: require('../images/TogetherPng.png'),
size: new AMap.Size(43, 50),
offset: new AMap.Pixel(-13, -30),
imageOffset:new AMap.Pixel(0, 0),
textColor:'#ffffff',
textSize: 20
}];
let Amap = this.map;
let markers = this.markers;
let cluster = this.cluster;
Amap.plugin(["AMap.MarkerClusterer"],function() {
cluster = new AMap.MarkerClusterer(Amap, markers, {
styles: sts,
gridSize: 80
});
});
} else {//默认样式
let Amap = this.map;
let markers = this.markers;
Amap.plugin(["AMap.MarkerClusterer"],function() {
cluster = new AMap.MarkerClusterer(Amap, markers, {gridSize: 80});
});
}
},
mapSetZoom(){
},
//缩放比例回调
mapZoomend(){
let zoom = this.map.getZoom();
console.debug(zoom + "缩放比例")
},
clearMap(){
this.map.clearMap();
},
// 实例化地图
async initMap () {
// 加载PositionPicker,loadUI的路径参数为模块名中 'ui/' 之后的部分
this.AMapUI = window.AMapUI;
let AMapUI =window.AMapUI;
let AMap = this.AMap = window.AMap;
if (typeof (AMapUI) == "undefined"){
}
AMapUI.loadUI(['misc/PositionPicker'], PositionPicker => {
let mapConfig = {
zoom: 14,//初始化地图层级
// cityName: MapCityName,
resizeEnable: true //是否监控地图容器尺寸变化
};
if (this.lat && this.lng) {
mapConfig.center = [this.lng, this.lat]
}
let marker, map = new AMap.Map('js-container', mapConfig);
this.map = map;
this.marker = marker;
this.initMapMaker();
map.on('zoomend', this.mapZoomend);
map.on('click', this.showInfoClick);
let city = this.logMapinfo();
// 启用工具条
AMap.plugin(['AMap.ToolBar'], function () {
map.addControl(new AMap.ToolBar({
position: 'RB'
}))
});
// 创建地图拖拽
let positionPicker = new PositionPicker({
mode: 'dragMap', // 设定为拖拽地图模式,可选'dragMap'、'dragMarker',默认为'dragMap'
map: map // 依赖地图对象
});
// 拖拽完成发送自定义 drag 事件
positionPicker.on('success', () => {
// 过滤掉初始化地图后的第一次默认拖放
if (!this.dragStatus) {
this.dragStatus = true
}
});
// 启动拖放
positionPicker.start();
//绑定地图移动事件
map.setCity(city);
});
}
},
async created () {
this.initInfo();
},
}
</script>
<style>
/**
局部覆盖原生样式
*/
.my_input .el-input__inner{
background:rgba(28,29,29,1);
border:1px solid rgba(0,0,0,1);
border-radius:20px;
}
</style>
<style lang="css">
.amap-logo {
display: none;
}
.amap-copyright {
opacity:0;
}
.my_input{position: marker;width:400px;height:40px;}
.m-map{ width: 100%; height: 100%; position: relative; }
.m-map .map{ width: 100%; height: 100%; }
.m-map .search_gaode{ position: absolute; top: 30px; left: 10px; width: 285px; z-index: 1; }
.m-map .result{ max-height: 300px; overflow: auto; margin-top: 10px; }
.m-map .amap-marker-label{
border: none;
display: flex;
align-items: center;
justify-content: center;
font-family:Source Han Sans CN;
font-weight:400;
width:auto;
padding: 7px 15px 7px 15px;
height:41px!important;
background:rgba(19,19,24,1);
box-shadow:0px 3px 7px 0px rgba(0, 0, 0, 0.35);
border-radius:15px;
}
.m-map .amap-ui-misc-positionpicker{
display: none;
}
.m-map .map-name{
font-size:16px;
color: white;
display:flex;
flex-direction:column;
align-items:center
}
.m-map .map-email{
font-size:12px;
color: #A0A0A0;
}
</style>
引入的config.js
// 高德地图 key
export const MapKey = 'xxx';
//makers图标
export const BuildingPng = 'data:image/png;base64,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';
遇到的几大坑:
①在ajax返回值中this的指向会改变,只能在外部先定义才能指向到vue
②高德地图在嵌入页面的时候会出现加载地图不完整 让初始化方法async 方式
③maker的下标显示label 这里有个很麻烦的地方如果你的标签显示信息长度不相同动态的,它这里没有自动居中设置只能设置偏移量,我这里只是简单的数学计算让它居中,没有深入研究
④maker的监听事件也和①一样内部需要转this指向
label:{
content: '<div class="map-name"><span>'+mapName+'</span>'+span+'</div>',
offset: new AMap.Pixel(-55 + shifting, 55)
},
let that = this;
new AMap.event.addListener(this.marker, 'click', function(e) {
//得到的数据
that.$store.commit('setMapShow_uniqueKey', JSON.parse(JSON.stringify(e.target.getExtData())));
const { href } = that.$router.resolve({ name:'MapShow'});
window.open(href, '_blank', )
});