高德地图关键字查询和输入提示后查询踩坑记录

最近在接入高德地图1.4.15版本,其中有地图关键字查询输入提示后查询的功能,中间踩了很多坑,一度怀疑是高德的bug,最终发现是自己代码的问题,好在最终解决了,在此记录一下。

地图关键字查询

踩坑1:频繁的创建new AMap.PlaceSearch 实例。我一开始将创建new AMap.PlaceSearch 实例写在了handleSearchChange 事件中,这样会导致placeSearch.search的分页查询不准确,比如我一开始搜索北京,在panel中展示出来的是北京的列表;之后我又搜索济南,一开始在panel中展示的是济南的列表,点击分页页码后,在panel中展示出来的是北京的列表结果。

错误代码如下:
js 复制代码
<script>
export default {
  data() {
    return {
      amap: null,
      apanel: null,
      searchValue: "",
    };
  },
  methods: {
    loadScript(url, callback) {
     //省略
    },
    initMap() {
      // 省略
    },
    handleSearchChange() { 
      const placeSearch = new AMap.PlaceSearch({ // 这里这么写是错误的
        pageSize: 5, // 单页显示结果条数
        pageIndex: 1, // 页码
        map: this.amap,
        panel: "panel",
      }); //构造地点查询类
      this.placeSearch = placeSearch;
      this.placeSearch.search(this.searchValue, (status, result) => {
        console.log("status", status);
        console.log("result", result);
      });
    },
  },
  mounted() {
    this.loadScript(
      "https://webapi.amap.com/maps?v=1.4.15&key=你的key值&plugin=AMap.Scale,AMap.OverView,AMap.ToolBar,AMap.Autocomplete,AMap.PlaceSearch",
      this.initMap
    );
  },
};
</script>
错误截图
  1. 第一步:先搜索北京
  2. 第二步:搜索其他地点,比如济南,出现搜索结果后点击分页 3.可以看到搜索结果是错误的!!!一切都是因为在input框的change事件里频繁的创建new AMap.PlaceSearch实例。
关键字查询的正确的实现代码如下:

在初始化中建立new AMap.PlaceSearch实例

js 复制代码
<template>
  <div style="width: 100%; height: 100vh">
    <div ref="amap" id="container" style="height: 100%" />

    <div ref="apanel" id="panel" class="panel" />
    <div class="search-bar">
      <input
        placeholder="地图检索"
        prefix-icon="el-icon-search"
        v-model="searchValue"
        @change="handleSearchChange"
      />
    </div>
  </div>
</template>
<style>
.panel {
  position: absolute;
  background-color: white;
  max-height: 90%;
  overflow-y: auto;
  top: 10px;
  left: 100px;
  width: 280px;
}
.search-bar {
  position: fixed;
  width: 250px;
  padding: 20px 0;
  right: 20px;
  top: 20px;
  z-index: 10000;
  display: flex;
}

.search-bar .el-input {
  background: rgba(255, 255, 255, 0.2);
}
</style>
<script>
export default {
  data() {
    return {
      amap: null,
      apanel: null,
      searchValue: "",
    };
  },
  methods: {
    loadScript(url, callback) {
      // 加载高德地图js
      let script = document.createElement("script");

      script.type = "text/javascript";

      script.src = url;

      document.getElementsByTagName("head")[0].appendChild(script);

      script.onload = () => {
        callback();
      };
    },
    initMap() {
      let scale = new AMap.Scale({
        visible: true,
      });
      let toolBar = new AMap.ToolBar({
        visible: true,
      });
      let overView = new AMap.OverView({
        visible: true,
      });

      console.log([this.longitude, this.latitude]);
      this.amap = new AMap.Map("container", {
        //center: [longitude, latitude], //地图中心点
        zoom: 15, //地图级别
        mapStyle: "amap://styles/dark", //设置地图的显示样式
        viewMode: "2D", //设置地图模式
        lang: "zh_cn", //设置地图语言类型
        resizeEnable: true,
      });
      this.amap.addControl(scale);
      this.amap.addControl(toolBar);
      this.amap.addControl(overView);
      const placeSearch = new AMap.PlaceSearch({ //在初始化中建立new AMap.PlaceSearch实例
        pageSize: 5, // 单页显示结果条数
        pageIndex: 1, // 页码
        map: this.amap,
        panel: "panel",
      }); //构造地点查询类
      this.placeSearch = placeSearch;
    },
    handleSearchChange() {
      this.placeSearch.search(this.searchValue, (status, result) => {
        console.log("status", status);
        console.log("result", result);
      });
    },
  },
  mounted() {
    this.loadScript(
      "https://webapi.amap.com/maps?v=1.4.15&key=你的key值&plugin=AMap.Scale,AMap.OverView,AMap.ToolBar,AMap.Autocomplete,AMap.PlaceSearch",
      this.initMap
    );
  },
};
</script>

输入提示后查询

踩坑1:创建new AMap.PlaceSearch 实例时:

  1. 错误写法:将传入的map参数写为存放map的dom,即this.$refs.amap。

  2. 正确写法:这里的map参数应该写为创建的new AMap.Map实例。

输入提示后查询的正确的实现代码如下:
js 复制代码
<template>
  <div style="width: 100%; height: 100vh">
    <div ref="amap" id="container" style="height: 100%" />

    <div ref="apanel" id="panel" class="panel" />
    <div class="search-bar">
      <input
        placeholder="地图检索"
        prefix-icon="el-icon-search"
        v-model="searchValue"
        @change="handleSearchChange"
        id="tipinput"
      />
    </div>
  </div>
</template>
<style>
.panel {
  position: absolute;
  background-color: white;
  max-height: 90%;
  overflow-y: auto;
  top: 10px;
  left: 100px;
  width: 280px;
}
.search-bar {
  position: fixed;
  width: 250px;
  padding: 20px 0;
  right: 20px;
  top: 20px;
  z-index: 10000;
  display: flex;
}

.search-bar .el-input {
  background: rgba(255, 255, 255, 0.2);
}
</style>
<script>
export default {
  data() {
    return {
      amap: null,
      apanel: null,
      searchValue: "",
    };
  },
  methods: {
    loadScript(url, callback) {
      // 加载高德地图js
      let script = document.createElement("script");
      script.type = "text/javascript";
      script.src = url;
      document.getElementsByTagName("head")[0].appendChild(script);
      script.onload = () => {
        callback();
      };
    },
    initMap() {
      let scale = new AMap.Scale({
        visible: true,
      });
      let toolBar = new AMap.ToolBar({
        visible: true,
      });
      let overView = new AMap.OverView({
        visible: true,
      });

      this.amap = new AMap.Map("container", {
        //center: [longitude, latitude], //地图中心点
        zoom: 15, //地图级别
        mapStyle: "amap://styles/dark", //设置地图的显示样式
        viewMode: "2D", //设置地图模式
        lang: "zh_cn", //设置地图语言类型
        resizeEnable: true,
      });
      this.amap.addControl(scale);
      this.amap.addControl(toolBar);
      this.amap.addControl(overView);
      const autoOptions = {
        input: "tipinput",
      };
      const auto = new AMap.Autocomplete(autoOptions);
      const placeSearch = new AMap.PlaceSearch({
        pageSize: 5, // 单页显示结果条数
        pageIndex: 1, // 页码
        map: this.amap, // 这里填写new AMap.Map的实例
        panel: "panel",
      }); //构造地点查询类
      AMap.event.addListener(auto, "select", select); //注册监听,当选中某条记录时会触发
      function select(e) {
        placeSearch.search(e.poi.name, (status, result) => {
          console.log("status", status);
          console.log("result", result);
        });
      }
      this.placeSearch = placeSearch;
    },
    handleSearchChange() {
      this.placeSearch.search(this.searchValue, (status, result) => {
        console.log("status", status);
        console.log("result", result);
      });
    },
  },
  mounted() {
    this.loadScript(
      "https://webapi.amap.com/maps?v=1.4.15&key=095f388e7a22189c7cb0095485e1ca59&plugin=AMap.Scale,AMap.OverView,AMap.ToolBar,AMap.Autocomplete,AMap.PlaceSearch",
      this.initMap
    );
  },
};
</script>
最终实现截图
相关推荐
前端不太难6 分钟前
从 Navigation State 反推架构腐化
前端·架构·react
前端程序猿之路40 分钟前
Next.js 入门指南 - 从 Vue 角度的理解
前端·vue.js·语言模型·ai编程·入门·next.js·deepseek
大布布将军1 小时前
⚡️ 深入数据之海:SQL 基础与 ORM 的应用
前端·数据库·经验分享·sql·程序人生·面试·改行学it
川贝枇杷膏cbppg1 小时前
Redis 的 RDB 持久化
前端·redis·bootstrap
D_C_tyu1 小时前
Vue3 + Element Plus | el-table 表格获取排序后的数据
javascript·vue.js·elementui
JIngJaneIL1 小时前
基于java+ vue农产投入线上管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
天外天-亮2 小时前
v-if、v-show、display: none、visibility: hidden区别
前端·javascript·html
jump_jump2 小时前
手写一个 Askama 模板压缩工具
前端·性能优化·rust
be or not to be2 小时前
HTML入门系列:从图片到表单,再到音视频的完整实践
前端·html·音视频
90后的晨仔3 小时前
在macOS上无缝整合:为Claude Code配置魔搭社区免费API完全指南
前端