vue使用高德地图关键字搜索功能的实例代码(踩坑经验)

目录

一、如何在Vue中引入基础高德地图

步骤一:注册并登录高德地图开发平台,申请密钥​编辑

   步骤二:安装高德地图加载器

二、 项目效果图

三、完整项目代码 

1、子组件 position.vue(看这个)

 2.在父组件引入position.vue

四、总结-------项目避坑(踩坑)

1、第一个坑:因为我用的element-ui的dialog组件,vue 页面或者弹窗使用 高德地图组件 map组件 不能加载 。

 2、第2个坑 搜索的时候 关键字列表出不来

3、补充知识点:Z-index属性详解


一、如何在Vue中引入基础高德地图

根据官网提示,在Web端,我们需要高德地图加载器:npm i @amap/amap-jsapi-loader -S
  • 步骤一:注册并登录高德地图开发平台,申请密钥

 

  •    步骤二:安装高德地图加载器

npm  i  @amap/amap-jsapi-loader -S

二、 项目效果图

三、完整项目代码 

1、子组件 position.vue(看这个)

<template>
  <div>
    <el-dialog
      :close-on-click-modal="false"
      title="选取打卡地址"
      :visible="positionDialog"
      :before-close="closePositionDialog"
      @close="closePositionDialog"
      append-to-body
      width="800px"
    >
      <div class="content">
        <div class="search-box">
          <div class="label">关键字搜索</div>
          <el-input
            v-model="input"
            placeholder="请输入内容"
            id="tipinput"
          ></el-input>
        </div>
        <div ref="map" id="map-container"></div>
      </div>

      <span slot="footer">
        <el-button @click="closePositionDialog" size="medium">取消</el-button>
        <el-button type="primary" @click="handlePositionDialog" size="medium"
          >确定</el-button
        >
      </span>
    </el-dialog>
  </div>
</template>

<script>
    import AMapLoader from "@amap/amap-jsapi-loader";

    window._AMapSecurityConfig = {
        // 设置安全密钥
        securityJsCode: "你自己的安全密钥",
    };

    export default {
        props: {
            positionDialog: {
                type: Boolean,
                default: false,
            },
        },
        data() {
            return {
                input: "",
                map: null,
                lnglat: [], //   [longitude,latitude]
                auto: null,
                placeSearch: null,
                markers: [],
                position: {}, //传给父组件的值【放经纬度和地址】
            };
        },
        watch: {
            // 监听事件 如果打开了弹框才加载地图,否则不加载地图
            positionDialog(type) {
                if (type) {
                    //type True or false
                    this.initMap();
                }
            },
        },

        methods: {
            async initMap() {
                await this.$nextTick();
                console.log(this.$refs.map);
                AMapLoader.load({
                        key: "你自己的key值", // 申请好的Web端开发者Key,首次调用 load 时必填
                        version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
                        plugins: ["AMap.AutoComplete", "AMap.PlaceSearch", "AMap.Geocoder"],
                    })
                    .then((AMap) => {
                        console.log(AMap);
                        this.map = new AMap.Map("map-container", {
                            // 设置地图容器id
                            viewMode: "3D", //  是否为3D地图模式
                            zoom: 18, // 初始化地图级别
                            center: [113.435871, 23.163298], //中心点坐标
                            resizeEnable: true,
                        });
                        // 关键字查询
                        this.searchMap();
                        // 监听鼠标点击事件
                        this.map.on("click", this.clickMapHandler);




                    })
                    .catch((e) => {
                        console.log(e);
                    });
            },

            // 点击地图事件获取经纬度,并添加标记
            clickMapHandler(e) {
                this.lnglat = [e.lnglat.getLng(), e.lnglat.getLat()];
                this.setMarker(this.lnglat);
                console.log(e, "点击地图", this.lnglat);
                // 点击地图上的位置,根据经纬度转换成详细地址
                let geocoder = new AMap.Geocoder({});
                let that = this;
                geocoder.getAddress(this.lnglat, function(status, result) {
                    console.log(status, result);
                    if (status === "complete" && result.regeocode) {
                        console.log(result.regeocode);
                        that.address = result.regeocode.formattedAddress;
                    } else {
                        console.log("查询地址失败,请稍后再试");
                    }
                });
                this.position = {
                    longitude: e.lnglat.getLng(),
                    latitude: e.lnglat.getLat(),
                    address: that.address,
                };
                this.input = that.address //把查询到的地址赋值到输入框
            },
            // 关键字查询
            searchMap() {
                // 搜索框自动完成类
                this.auto = new AMap.AutoComplete({
                    input: "tipinput", // 使用联想输入的input的id
                });
                //构造地点查询类
                this.placeSearch = new AMap.PlaceSearch({
                    map: this.map,
                });
                // 当选中某条搜索记录时触发
                this.auto.on("select", this.selectSite);
                console.log(this.selectSite, "select");
            },
            //当选中某条搜索记录时触发
            selectSite(e) {
                if (e.poi.location) {
                    console.log("经纬度", e);
                    this.lnglat = [e.poi.location.lng, e.poi.location.lat];
                    this.placeSearch.setCity(e.poi.adcode);
                    this.placeSearch.search(e.poi.name); //关键字查询
                    let geocoder = new AMap.Geocoder({});
                    let that = this;
                    geocoder.getAddress(this.lnglat, function(status, result) {
                        if (status === "complete" && result.regeocode) {
                            that.province = result.regeocode.addressComponent.province;
                            that.city = result.regeocode.addressComponent.city;
                            //自己想要赋的值,根据自己的做修改
                            that.$set(that.form, "province", that.province);
                            that.$set(that.form, "city", that.city);
                            that.$set(that.form, "address", e.poi.name);
                            that.$set(
                                that.form,
                                "coordinate",
                                e.poi.location.lng + "," + e.poi.location.lat
                            ); //纬度,经度
                            console.log(that.form, "地址");
                        } else {
                            console.log("查询地址失败,请稍后再试");
                        }
                    });
                } else {
                    this.$message.error("查询地址失败,请重新输入地址");
                }
            },
            //  添加标记
            setMarker(lnglat) {
                this.removeMarker();
                console.log("位置", lnglat);
                let marker = new AMap.Marker({
                    position: lnglat,
                });
                marker.setMap(this.map);
                this.markers.push(marker);
            },
            // 删除之前后的标记点
            removeMarker() {
                if (this.markers) {
                    this.map.remove(this.markers);
                }
            },
            closePositionDialog() {
                this.input = "";
                this.position = {}
                this.$emit("update:positionDialog", false);
            },
            handlePositionDialog() {
                this.$emit("selPosition", this.position); //把选择的位置传给父组件
                this.closePositionDialog();
            },
        },
    };
</script>

<style lang="scss">
    .search-box {
        display: flex;
        justify-content: flex-start;
        align-items: center;
        height: 50px;
        .label {
            width: 100px;
        }
    }

    .content {
        position: relative;
    }

    #panel {
        position: absolute;
        top: 50px;
        right: 20px;
    }

    #map-container {
        overflow: hidden;
        width: 100%;
        height: 700px;
        margin: 0;
    }

    .amap-sug-result {
        z-index: 2999 !important;
    }
</style>

 2.在父组件引入position.vue

父组件引入一小部分,这里不影响效果,核心部分在position.vue

        <el-form-item label="打卡位置" prop="address">
          <el-button size="mini" type="info"
            :disabled="dialogType == 'detail'"
            @click="positionDialog = true"
          >选择打卡位置
          </el-button>
             <el-tag type="success" v-if="rowData.address"  >{{rowData.address  }}</el-tag>
          <div>
            打卡活动经度:
            <el-tag type="danger" effect="plain" >{{
              rowData.longitude ? rowData.longitude : "选择好位置后自动获取"
            }}</el-tag>
          </div>
          <div>
            打卡活动纬度:
            <el-tag type="danger" effect="plain">{{
              rowData.latitude ? rowData.latitude : "选择好位置后自动获取"
            }}</el-tag>
          </div>

          <!-- 对话框【打卡位置选择】 -->
          <position 
          :positionDialog.sync="positionDialog"
          @selPosition="(position)=>{
            rowData.latitude=position.latitude
            rowData.longitude=position.longitude
            rowData.address=position.address
          }"
          />
        </el-form-item>

四、总结-------项目避坑(踩坑)

我摸索了很久,很不容易,才解决这2个坑

1、第一个坑:因为我用的element-ui的dialog组件,vue 页面或者弹窗使用 高德地图组件 map组件 不能加载 。

我遇到的问题是:

高德地图在页面中引用能够正常显示(在其他页面没有使用el-dialog组件),但是想在el-dialog中显示高德地图并进行操作,地图无法显示。

为什么呢?因为是当我点击添加活动列表时,打开了第一层弹框的组件,这个时候第二层的弹框组件还没有打开,但是确已经加载了地图,所以我们不能在mounted里面初始化地图

2层组件

1、主要原因是当前生命周期mounted执行完成后,第2个组件页面el-dialog元素并不存在,所有无法显示地图。

解决方案:先确保拿到数据,再加载地图,我在这里使用watch监听,原理就是当第2个el-dialog组件为true的时候才加载地图

  watch:{
    // 监听事件 如果打开了弹框才加载地图,否则不加载地图
    //positionDialog是控制弹框是否显示的值
    positionDialog(type){
      if(type){
        //type: True or false
        this.initMap(); 
      }
    }
  },

 2、第2个坑 搜索的时候 关键字列表出不来

了解到是由于层级的原因

解决方案:

高德地图搜索框没有效果的原因可能是因为搜索的结果在地图的图层底下,所以不显示,疯狂在本页面进行css穿透改各种样式,结果还是不生效,没办法那就在全局样式中加了一段这里记录一下css样式级别: 行内>内部>外部,全局>页面而这次在全局里写样式是因为我这段高德地图是引入第三方的东西,它的css可能不在我的本页面内存放或者级别高于我本页面的样式,所以在本页面穿透解决不了它,在全局可以解决有一个要注意的是,级别越高,影响越大,例如在本项目的其它地方使用到class='amap-sug-result’时,它都会添加以下样式了,所以在能实现的基础上,级别越低越好

//然后我就在主页面,也就是我的App.vue人口文件加了这个,效果就出来了
.amap-sug-result{
  z-index: 9999!important;
}

3、补充知识点:Z-index属性详解

1.概念

z-index 属性设置元素的堆叠顺序。拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面。

 案例:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>z-index Demo</title>
		<style type="text/css">
			div{
				width: 200px;height: 200px;
				text-align: center;
				font-size: 50px;
				line-height: 200px;
				position: absolute;
				}
				
			#red{left: 100px;top: 100px;}
			#green{left: 200px;top: 200px;}
		</style>
	</head>
	<body>
		<!-- Z-index层叠性原则:
					1.同层级元素(或position:static)默认情况下文档流后面的元素会覆盖前面的。(后来居上)
					2. 对于同级元素,position不为static且z-index存在的情况下z-index大的元素会覆盖z-index小的元素,
					   即z-index越大优先级越高。 -->
					   
		<div id="red" style="background: red;z-index: 0;">A</div>
		<div id="green" style="background-color: green;">B</div>
		<div id="blue" style="background-color: blue;z-index: -1;">C</div>
	</body>
</html>

以上就是我踩坑总结出来的,该项目的代码可以直接复制,我踩的坑已经补上去了 ,如果有不明白的或者一些错误,希望大家指出来,大家一起探讨!

  • 14
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
Vue使用高德地图的聚合点功能,首先需要安装并引入高德地图JavaScript API。 1. 在`index.html`文件中,添加如下代码引入高德地图的API: ```html <script src="https://webapi.amap.com/maps?v=1.4.15&key=your_api_key"></script> ``` 其中,`your_api_key`是你在高德地图开放平台申请的API Key。 2. 在Vue组件中,首先在`mounted`生命周期钩子中初始化地图,并创建一个地图实例: ```javascript mounted() { // 初始化地图 AMap.initAMapApiLoader({ key: 'your_api_key', plugin: ['AMap.MarkerClusterer'] }); // 创建地图实例 this.map = new AMap.Map('mapContainer', { center: [lng, lat], // 地图中心点经纬度 zoom: 13 // 地图缩放级别 }); } ``` 3. 在数据加载完成后,将需要聚合的点数据添加到地图上: ```javascript addMarkers() { this.points.forEach(point => { let marker = new AMap.Marker({ position: [point.lng, point.lat] // 标记点位置经纬度 }); this.map.add(marker); }); } ``` 其中,`this.points`是包含标记点经纬度的数组。 4. 最后,启用聚合点功能,将添加的标记点进行聚合: ```javascript clusterMarkers() { let cluster = new AMap.MarkerClusterer(this.map, this.map.getAllOverlays(), { gridSize: 80, // 聚合点的像素大小 renderCluserMarker(cluster) { let count = cluster.getMarkers().length; let div = document.createElement('div'); div.className = 'cluster-marker'; div.innerHTML = count; return new AMap.Icon({ size: new AMap.Size(40, 40), image: 'cluster.png', imageSize: new AMap.Size(40, 40), // 自定义聚合点的样式和内容 div: div }); } }); } ``` 通过`AMap.MarkerClusterer`类创建一个聚合器对象,将地图实例、添加的标记点和聚合选项传入。 以上就是在Vue使用高德地图聚合点功能的基本步骤。根据实际需求,可以进一步添加交互、自定义样式等功能

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值