vue2(webpack)调用amap高德地图及其UI组件和标记物

本文详细介绍如何在Vue项目中集成高德地图SDK,包括申请密钥、配置环境、地图初始化、添加控件、定位、标记物与信息窗口等功能实现步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文转载自:http://blog.youkuaiyun.com/yp090416/article/details/74900870?ref=myrecommend

今天一个app项目中要使用vue2加入高德地图,本来以为有第三方的插件,结果没找到适合自己用的,因为地图这块,一般都是自定义程度比较高的。注:这块针对的是app版开发,更多更详细请阅读官方api

1、申请key

点击下边的网址,创建应用,然后申请key,后期要用到,如果已经有key,忽略这一步 http://lbs.amap.com/dev/key/app

2、修改配置

首先要在build/webpack.base.conf.js 加入如下配置,负责vue中使用import会报错。 如果如下导入还AMap报错,请使用window.AMap。因为后边要使用高德的infowindow,最简单的不好扩展,而且没有点击事件,所以用用到了高德的ui。位置见下图

externals: {
    'AMap': 'AMap',
    'AMapUI': 'AMapUI'
  }

这里写图片描述

3、调用高德地图

  • 首先在index.html中加入如下引用
<!--引入高德地图JSAPI -->
<script src="//webapi.amap.com/maps?v=1.3&key=您申请的key值"></script>

<!--引入UI组件库(1.0版本) -->
<script src="//webapi.amap.com/ui/1.0/main.js"></script>
  • 新建一个map.vue组件

在script中引入如下组件,如果第二步不配置,这里会报错

import AMap from 'AMap'
import AMapUI from 'AMapUI'

如果前边都操作了,import AMap还报错undefined的话,有个终极大招,那就是直接加入如下注释,并且把 import AMap 删除掉,意思是告诉eslint忽略这块的检查,因为在index.html引入是全局引入,所以可以直接使用。 
这里写图片描述

template中加入map的div,注意如果map不显示,没报错的时候,请检查div的宽高。

<div id="map-container"> </div>

然后再mounted中初始化地图,这时候地图就会显示出来了,但是没有任何组件,注意vue2废弃ready,请使用mounted。代码位置不懂的看图片 

这里写图片描述

<!--创建地图 -->
let mapObj = new AMap.Map('map-container', {
          center: [117.000923, 36.675807],
          zoom: 6
        })

两个组件:放大缩小按钮和图层的切换

mapObj.plugin(['AMap.ToolBar', 'AMap.MapType'], function () {
  mapObj.addControl(new AMap.ToolBar())
  mapObj.addControl(new AMap.MapType({showTraffic: false, showRoad: false}))
        })

使用高德定位

mapObj.plugin(['AMap.Geolocation'], function () {
          let geolocation = new AMap.Geolocation({
            enableHighAccuracy: true, //  是否使用高精度定位,默认:true
            timeout: 10000, //  超过10秒后停止定位,默认:无穷大
            maximumAge: 0, // 定位结果缓存0毫秒,默认:0
            convert: true, // 自动偏移坐标,偏移后的坐标为高德坐标,默认:true
            showButton: true, //  显示定位按钮,默认:true
            buttonPosition: 'LB',  // 定位按钮停靠位置,默认:'LB',左下角
            buttonOffset: new AMap.Pixel(10, 20), //  定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
            showMarker: true, //  定位成功后在定位到的位置显示点标记,默认:true
            showCircle: true, //  定位成功后用圆圈表示定位精度范围,默认:true
            panToLocation: true,  //  定位成功后将定位到的位置作为地图中心点,默认:true
            zoomToAccuracy: true  //  定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
          })
          mapObj.addControl(geolocation)
          geolocation.getCurrentPosition()
          AMap.event.addListener(geolocation, 'complete', (result) => {
            mapObj.setCenter(result.position)
          })  //  返回定位信息
          AMap.event.addListener(geolocation, 'error', (result) => {
            console.log(result)
          })  //  返回定位出错信息
        })

这里写图片描述

4、地图添加标记物和信息框 marker和infowindow

因为我从后台取到的点是gps定位的点,因为坐标系不同,所以要将gps的点转成高德坐标系的点;点击marker显示infowindow,并给infowindow添加点击事件

// 后台取到的点,新建LngLat对象
          let lngLat = new AMap.LngLat(lanlet[0].trim(), lanlet[1].trim())
          // 转高德坐标系
          AMap.convertFrom(lngLat, 'gps', function (info, result) {
            lngLat = result.locations[0]// 转换后的坐标位置
            var marker = new AMap.Marker({
              position: lngLat,
              map: mapObj
            })
            AMap.event.addListener(marker, 'click', (e) => {
              AMapUI.loadUI(['overlay/SimpleInfoWindow'], function (SimpleInfoWindow) {
                var infoWindow = new SimpleInfoWindow({
                  infoTitle: '<strong>这是标题</strong>',
                  infoBody: '<p>这是信息</p>',
                  offset: new AMap.Pixel(0, -20),
                  autoMove: true
                })
                infoWindow.open(mapObj, e.target.getPosition())
                // 最坑的就是这一步了,他的infowindow没有点击事件,所以infoWindow.get$Container()会返回这个infowindow(jquery)对象
                let infoEle = infoWindow.get$Container()
                //给infowindow添加点击事件,并在回调函数中处理业务或者跳转等
                infoEle.on('click', (e) => {
                  router.push({name: 'proinfo', params: pro})
                })
              })
            })
          })

这里写图片描述

5、最后本人的效果图

这个title是准备做浮动布局,做返回按钮和标题栏的,还没写css 
这里写图片描述

### Vue2 高德地图组件自适应布局实现 #### 地图初始化与挂载 为了确保高德地图能够在Vue2项目中正常工作并响应窗口大小变化,推荐的地图实例创建方式是在`methods`选项内定义,并通过`mounted`生命周期钩子触发该方法。这有助于在DOM完全加载之后执行地图初始化逻辑[^1]。 ```javascript export default { data() { return { map: null, }; }, methods: { initMap() { this.map = new AMap.Map('container', { zoom: 10, // 设置地图显示的缩放级别 center: [116.397428, 39.90923], // 设置地图中心点坐标 }); } }, mounted() { this.initMap(); } } ``` #### 容器尺寸调整监听 为了让地图能够随着浏览器窗口的变化而动态调整其展示区域,可以在`created`或`mounted`阶段绑定事件处理器来侦听视窗大小改变事件。每当检测到变动时重新设定地图容器的高度宽度,并调用API刷新地图以匹配新的边界框[^2]。 ```javascript import { onMounted, onUnmounted } from 'vue'; // ...省略前面的部分... onMounted(() => { window.addEventListener('resize', handleResize); }); onUnmounted(() => { window.removeEventListener('resize', handleResize); }); const handleResize = () => { const container = document.getElementById('map-container'); if (this.map && container) { setTimeout(() => { this.map.setZoom(this.map.getZoom()); // 强制重绘地图 }, 100); // 延迟一段时间等待样式生效后再更新地图 }; ``` #### 使用Flexbox进行弹性布局设计 考虑到Element UI 的 Container 组件基于 Flexbox 构建,默认情况下已经支持水平方向上的自动伸展特性。对于垂直方向(即高度),可以通过CSS设置父级元素为相对定位(`position:relative`),并将`.el-main`类下的内容区设为绝对定位(`position:absolute;top:0;bottom:0;left:0;right:0`)的方式让内部的地图占据剩余空间。 ```css <style scoped> .el-container { position: relative; } .el-header, .el-footer { background-color: #B3C0D1; color: #333; text-align: center; line-height: 60px; } .el-aside { background-color: #D3DCE6; color: #333; text-align: center; line-height: 200px; } .el-main { position: absolute; top: 0; bottom: 0; left: 0; right: 0; padding: 0; } </style> ``` #### 结合PX转REM提升移动端适配能力 针对不同设备分辨率下UI的一致性表现问题,可以考虑引入`postcss-pxtorem`插件配合Webpack配置文件中的PostCSS loader使用,从而将固定像素单位转换成相对于根字体大小的比例值(REM),使得页面结构更加灵活地应对各种屏幕尺寸差异[^3]。 ```json { "plugins": [ require('autoprefixer'), require('postcss-pxtorem')({ rootValue: 16, /* 设定基数 */ propList: ['*'] /* 应用于所有属性 */ }) ] } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值