Vue项目接入高德地图

说明:最近开发中有需要使用英文版本的地图,比较下采用了高德地图(百度不支持英文JS API,谷歌需要visa信用卡认证),记录一下开发过程。

开发过程

  1. 申请密钥,地址:高德地图开放平台
  2. 在index.html中引入对应文件
<link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css" />
<link rel="stylesheet" type="text/css" href="https://a.amap.com/jsapi_demos/static/demo-center/css/prety-json.css">


<script type="text/javascript">
    window._AMapSecurityConfig = {
      securityJsCode: "安全密钥",
  }
</script>
<script src="https://cache.amap.com/lbs/static/es5.min.js"></script>
<script src="https://webapi.amap.com/maps?v=1.4.15&key=密钥KEY&plugin=AMap.Autocomplete"></script>
<script type="text/javascript" src="https://a.amap.com/jsapi_demos/static/demo-center/js/jquery-1.11.1.min.js" ></script>
<script type="text/javascript" src="https://a.amap.com/jsapi_demos/static/demo-center/js/underscore-min.js" ></script>
<script type="text/javascript" src="https://a.amap.com/jsapi_demos/static/demo-center/js/backbone-min.js" ></script>
<script type="text/javascript" src='https://a.amap.com/jsapi_demos/static/demo-center/js/prety-json.js'></script>
  1. 组件开发
  • 组件一
    功能:用于标记当前地点,提供搜索功能。
    代码:
<template>
  <div>
    <div id="container"></div>
  </div>
</template>

<script>
export default {
  props: {
    center: {
      type: Object,
      default: () => ({ lng: 0, lat: 0 }) 
    },
    zoom: {
      type: Number,
      default: 13
    }
  },
  data() {
    return {
      selectedLang: this.$i18n.locale === 'en' ? 'en' : 'zh_cn',
      map: null,
      marker: null,
      currentCenter: { lng: this.center.lng, lat: this.center.lat }, // 当前中心点
      searchMarkers: []  // 查找标记点
    };
  },
  mounted() {
    this.initMap();
  },
  beforeDestroy() {
    if (this.map) {
      this.map.destroy();
    }
  },
  methods: {
    // 初始化地图
    initMap() {
      this.initializeMap(this.currentCenter);

      // 地图点击事件
      AMap.event.addListener(this.map, 'click', (e) => {
        this.currentCenter = { lng: e.lnglat.getLng(), lat: e.lnglat.getLat() }; 
        this.addMarker(this.currentCenter); 
        this.$emit('updateCenter', this.currentCenter); 
      });

      // 语言切换
      this.$watch('selectedLang', (newLang) => {
        this.map.setLang(newLang);
      });

      // 地图缩放事件,告诉父组件当前层级
      AMap.event.addListener(this.map, 'zoomend', () => {
        const currentZoom = this.map.getZoom();
        this.$emit('curMapLevel', currentZoom); 
      });
    },
    
    // 初始化地图
    initializeMap(center) {
      if(center.lng == null || center.lat == null){
        this.map = new AMap.Map('container', {
          resizeEnable: true,
          lang: this.selectedLang,
          zoom: this.zoom
        });
      }else{
        this.map = new AMap.Map('container', {
          resizeEnable: true,
          center: [center.lng, center.lat],
          lang: this.selectedLang,
          zoom: this.zoom
        });
        this.addMarker(center);
      }
    },
    // 搜索关键词
    searchKeywords(keywords) {
      AMap.plugin('AMap.Autocomplete', () => {
        var autoOptions = {
          city: '全球',
          lang: this.selectedLang
        }
        var autoComplete = new AMap.Autocomplete(autoOptions);
        autoComplete.search(keywords, (status, result) => {
          console.log(result);
          if (status === 'complete' && result.info === 'OK') {
              this.addSearchMarkers(result.tips); 
          } else {
              console.error('自动完成失败:', result.info);
          }
        });
      });
    },
    addMarker(position) {
      if (this.marker) {
        this.marker.setMap(null); 
      }
      this.marker = new AMap.Marker({
        position: [position.lng, position.lat]
      });
      this.marker.setMap(this.map);
    },
    // 添加搜索标记点
    addSearchMarkers(tips) {
      this.searchMarkers.forEach(marker => marker.setMap(null));
      this.searchMarkers = [];

      if (tips.length > 0) {
        this.map.setCenter([tips[0].location.lng, tips[0].location.lat]);
        
        const firstTip = tips[0];
        const firstMarkerPosition = [firstTip.location.lng, firstTip.location.lat];
        const infoWindow = new AMap.InfoWindow({
          content: `<div><strong>${firstTip.name}</strong> <span style="color: #3d6dcc; cursor: pointer;" onclick="window.open('https://www.amap.com/detail/${firstTip.id}')">` + this.$t('common.detail') +`»</span><br>${firstTip.address}</div>`,
          offset: new AMap.Pixel(0, -30) 
        });
        infoWindow.open(this.map, firstMarkerPosition); 
      }
      // 添加搜索标记点
      tips.forEach(tip => {
        const marker = new AMap.Marker({
          position: [tip.location.lng, tip.location.lat],
          icon: new AMap.Icon({
            size: new AMap.Size(25, 34), 
            image: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png',
            imageSize: new AMap.Size(25, 34), 
          })
        });
        marker.setMap(this.map);
        this.searchMarkers.push(marker); 

        // 点击事件,显示详情
        marker.on('click', () => {
          const infoWindow = new AMap.InfoWindow({
            content: `<div><strong>${tip.name}</strong> <span style="color: #3d6dcc; cursor: pointer;" onclick="window.open('https://www.amap.com/detail/${tip.id}')">` + this.$t('common.detail') +`»</span><br>${tip.address}</div>`, // Display name and detail button in the same line
            offset: new AMap.Pixel(0, -30) 
          });
          infoWindow.open(this.map, marker.getPosition()); 
          this.currentCenter = { lng: tip.location.lng, lat: tip.location.lat };
          this.$emit('updateCenter', this.currentCenter);
        });
      });
    },
  }
};
</script>

<style scoped>
#container {
  width: 100%;
  height: calc(100vh - 200px);
  margin: 0px;
}
</style>

使用示例:

import GaoDeMap from './gaode'
<gao-de-map ref="mapSelectRef" 
  :center='position' 
  :zoom="zoom" 
  @updateCenter="positionSelect"
  @curMapLevel="mapLevel">
</gao-de-map>

  • 组件二
    功能:用于显示多个标记点位置及标记点详情
    代码:
<template>
  <div ref="mapContainer" class="map-container"></div>
</template>

<script>
export default {
  data() {
    return {
      map: null,
      markers: [], // 存储标记点
      currentInfoWindow: null, // 当前信息窗口
      selectedLang: this.$i18n.locale === 'en' ? 'en' : 'zh_cn', // 语言选择
    };
  },
  watch: {
  },
  methods: {
    initMap() {
      this.map = new AMap.Map(this.$refs.mapContainer, {
        zoom: 13,
        lang: this.selectedLang,
      });
    },
    // 初始化设备标记点
    initDeviceMarkers(newData) {
      this.markers.forEach(marker => marker.setMap(null));
      this.markers = [];

      newData.forEach((device) => {
        if (device.lng != null && device.lat != null && device.lng != '' && device.lat != '') {
          const marker = new AMap.Marker({
            position: [device.lng, device.lat],
            content: `<img src="${require('@/assets/images/device_map.png')}" style="width:30px;height:41px;">`,
            offset: new AMap.Pixel(-15, -15),
          });

          marker.setMap(this.map);
          this.markers.push(marker); 

          marker.on('mouseover', () => {
            this.$emit('deviceMouseOver', device);
          });

          //鼠标离开标记点,关闭气泡
          marker.on('mouseout', () => {
            if (this.currentInfoWindow) {
              this.currentInfoWindow.close();
            }
          });

          marker.on('click', () => {
            this.$emit('deviceClick', device);
          });
        }
      });
    },
    // 显示信息窗口
    showPopupAtMarker(device, popupHtml) {
      if (this.currentInfoWindow) {
        this.currentInfoWindow.close();
      }

      const infoWindow = new AMap.InfoWindow({
        content: popupHtml,
        offset: new AMap.Pixel(0, -30),
      });

      const marker = this.markers.find(m => m.getPosition().equals(new AMap.LngLat(device.lng, device.lat)));
      if (marker) {
        infoWindow.open(this.map, marker.getPosition());
        this.currentInfoWindow = infoWindow; 
      }
    },
  },
  mounted() {
    this.initMap();
  },
};
</script>

<style scoped>
.map-container {
  width: 100%;
  height: 100%;
}
</style>

使用示例:

import GaodeDeviceMap from './gaode'
<gaode-device-map
  ref="gaodeDeviceMap" 
  @deviceMouseOver="handleDeviceMouseOver"
  @deviceClick="handleDeviceClick"
/>

补充

vue-amap
amap-jsapi-loader

posted @   IamHzc  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示
主题色彩