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

最近在接入高德地图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>
最终实现截图
相关推荐
重铸码农荣光7 分钟前
深入理解 JavaScript 原型链:从 Promise.all 到动态原型的实战探索
前端·javascript·promise
进击的野人12 分钟前
深入理解 Async/Await:现代 JavaScript 异步编程的优雅解决方案
javascript·面试·ecmascript 6
我叫黑大帅14 分钟前
什么叫可迭代对象?为什么要用它?
前端·后端·python
颜渊呐15 分钟前
Vue3 + Less 实现动态圆角 TabBar:从代码到优化实践
前端·css
PineappleCoder18 分钟前
pnpm 凭啥吊打 npm/Yarn?前端包管理的 “硬链接魔法”,破解三大痛点
前端·javascript·前端工程化
fruge23 分钟前
前端文档自动化:用 VitePress 搭建团队技术文档(含自动部署)
运维·前端·自动化
CoolerWu1 小时前
TRAE SOLO实战成功展示&总结:一个所见即所得的笔记软体
前端·javascript
Cassie燁1 小时前
el-button源码解读1——为什么组件最外层套的是Vue内置组件Component
前端·vue.js
vx_bscxy3221 小时前
告别毕设焦虑!Python 爬虫 + Java 系统 + 数据大屏,含详细开发文档 基于web的图书管理系统74010 (上万套实战教程,赠送源码)
java·前端·课程设计
北极糊的狐1 小时前
Vue3 子组件修改父组件传递的对象并同步的方法汇总
前端·javascript·vue.js