vue 引入百度地图api遇到的一些问题

467 阅读2分钟

引入问题

在vue的public下面的index.html中引入

	<script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak=您的密钥"></script>

因为这是一个异步的过程,不能直接在组件中调用,需要把Bmap挂载到windows上

  mounted() {
    var that = this;
    that.$nextTick(that.createMap(window.BMap));
  },
    createMap(BMap) {
      // 百度地图API功能
      let map = new BMap.Map("allmap"); // 创建Map实例
      map.centerAndZoom(new BMap.Point(113.668868, 34.750949), 12); // 初始化地图,设置中心点坐标和地图级别
      //添加地图类型控件
      map.setCurrentCity("郑州"); // 设置地图显示的城市 此项是必须设置的
      map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放
    },

地图组件封装之后调用,出现地图只加载了一次,

问题是百度地图挂载显示的时候,需要获取Dom元素的id,如果存在的话就不去加载了, 解决办法:把定义的地图组件ID自定义,根据组件传值过改变

<template>
  <div class="popup" v-show="showPopup" @mousewheel.prevent>
    <div class="content">
      <div class="map" :id="mapId || 'map'"></div>
      <div class="input-auto">
        <div class="label">{{title}}</div>
        <div class="input-right">
          <input class="input" v-model="formData.popAddress" :placeholder="placeholder" type="text" />
          <div class="menu">
            <div
              class="menu-item"
              v-for="(item,index) in list"
              :key="index"
              @mouseenter="enter(index)"
              @mouseleave="leave"
            >
              <img class="icon" src=".././assets/circle.png" alt />
              <div class="text">
                <div class="name">{{ item.name }}</div>
                <span class="addr">{{ item.address }}</span>
              </div>
              <div v-if="activeIndex==index" class="select" @click="selectChange(item)">选中</div>
            </div>
          </div>
        </div>
      </div>
      <div class="close" @click="close">
        <img src=".././assets/close.png" alt />
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: "Popup",
  props: {
    showDialog: Boolean,
    title: String,
    placeholder: String,
    mapId: String
  },
  data() {
    return {
      formData: {
        popAddress: "",
        poplocation: ""
      },
      list: [],
      activeIndex: -1,
      showPopup: false,
      searchTitle: "",
      lag: "",
      lat: ""
    };
  },
  computed: {
    address_change() {
      return this.formData.popAddress;
    }
  },
  watch: {
    address_change() {
      this.querySearchAsync();
      this.searchTitle = this.formData.popAddress;
      var that = this;
      that.$nextTick(that.searchMap(window.BMap));
    },
    showDialog() {
      if (this.showDialog) {
        this.showPopup = this.showDialog;
      }
    }
  },
  mounted() {
    var that = this;
    that.$nextTick(that.createMap(window.BMap));
  },
  methods: {
    createMap(BMap) {
      // 百度地图API功能
      let map = new BMap.Map(this.mapId || "map"); // 创建Map实例
      map.centerAndZoom(new BMap.Point(113.668868, 34.750949), 12); // 初始化地图,设置中心点坐标和地图级别
      //添加地图类型控件
      map.setCurrentCity("郑州"); // 设置地图显示的城市 此项是必须设置的
      map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放
    },
    searchMap(BMap) {
      // 百度地图API功能
      var map = new BMap.Map(this.mapId || "map");
      map.centerAndZoom(new BMap.Point(113.668868, 34.750949), 12);
      var local = new BMap.LocalSearch(map, {
        renderOptions: { map: map }
      });
      local.search(this.searchTitle);
    },

    querySearchAsync() {
      let obj = {
        query: this.formData.popAddress,
        region: "郑州",
        output: "json",
        ak: "NnbxvMwk23WZyuSk20mnAQ6SdK53Blcy"
      };
      this.$jsonp("http://api.map.baidu.com/place/v2/search", obj)
        .then(response => {
          let res = response.results.filter(item => item.detail);
          this.list = res;
        })
        .catch(() => {});
    },
    handleSelect(item) {
      this.formData.popAddress = item.address; //记录详细地址
      this.formData.poplocation = item.location; //记录详细地址
      this.$emit("delChange", this.formData);
    },
    enter(val) {
      this.activeIndex = val;
      this.searchTitle = this.list[val].name;
      this.$nextTick(this.searchMap(window.BMap));
    },
    leave() {
      this.activeIndex = -1;
    },
    selectChange(item) {
      this.formData.popAddress = item.address;
      this.formData.poplocation = item.location;
      this.showPopup = false;
      this.$emit("PopChange", this.formData);
    },
    close() {
      this.showPopup = false;
    }
  }
};
</script>
<style lang="less" scoped>
.popup {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 20;
  .content {
    width: 70%;
    height: 70%;
    background-color: #fff;
    position: relative;
    z-index: 2;
    .map {
      width: 99%;
      height: 98%;
      margin: 0.5%;
      box-sizing: border-box;
      z-index: 2;
    }
    .input-auto {
      position: absolute;
      top: 20px;
      left: 20px;
      display: flex;
      align-items: flex-start;
      z-index: 2;
      .label {
        font-size: 14px;
        color: #333;
        height: 40px;
        padding: 0 15px;
        box-sizing: border-box;
        background-color: #fff6f1;
        display: flex;
        align-items: center;
        justify-content: center;
      }
      .input-right {
        .input {
          width: 250px;
          height: 40px;
          border: none;
          outline: none;
          padding-left: 20px;
        }
        .menu {
          width: 270px;
          max-height: 300px;
          // overflow: hidden;
          overflow-y: auto;
          display: flex;
          border-top: solid #ddd 1px;
          flex-direction: column;
          background-color: #fff;
          // padding: 5px 0;
          .menu-item {
            display: flex;
            // flex-direction: column;
            padding: 5px 10px;
            align-items: center;
            position: relative;
            cursor: pointer;
            .icon {
              // width: 10px;
              // height: 10px;
              padding-right: 10px;
            }
            .text {
              display: flex;
              flex-direction: column;
              .name {
                width: 200px;
                font-size: 13px;
                text-overflow: ellipsis;
                overflow: hidden;
                white-space: nowrap;
              }
              .addr {
                width: 200px;
                font-size: 12px;
                color: #b4b4b4;
                text-overflow: ellipsis;
                overflow: hidden;
                white-space: nowrap;
              }
            }
          }
          :hover {
            background-color: gainsboro;
          }
          .select {
            position: absolute;
            top: 50%;
            right: 5px;
            width: 30px;
            height: 20px;
            border-radius: 1px;
            transform: translateY(-50%);
            background-color: coral;
            color: #fff;
            font-size: 12px;
            display: flex;
            align-items: center;
            justify-content: center;
          }
        }
      }

      .autocomplete {
        width: 200px;
        height: 40px;
        border-top-left-radius: 0% !important;
      }
    }
    .close {
      position: absolute;
      top: 0px;
      right: 15px;
      width: 30px;
      height: 30px;
      background-color: coral;
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;
    }
  }
}
</style>

2.使用

    <Popup
      :showDialog="showDialog"
      :title="title"
      :placeholder="placeholder"
      :mapId="mapId"
      @PopChange="PopChange"
    ></Popup>
import Popup from "../components/Popup";