环境: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', ) });