vue之百度地图的使用(二)

今天介绍百度地图搜索的第二种用法,之前记录过一种方法(详细可看百度地图的使用(一))。第一种方法是通过BMap.LocalSearch来自定义搜索,拿返回Yr参数去渲染页面。最近使用百度搜索发现不同的电脑返回的参数不一样,导致有的电脑搜索是null。若想继续使用这个方法,可以做以下改进。

const local = new this.BMap.LocalSearch(this.map, {
        renderOptions: {
          map: this.map,
          selectFirstResult: false
        },
        onSearchComplete: function(res) {
          console.log('results', res)
          if (res && (res.Yr || res.as)) { // 若res.Yr不存在则取res.as,在网上没找到为什么会返回不一样的参数,但目前只发现这两种。
            this.searchResult = [...(res.Yr || res.as)]
          }
        }
      })
      local.search(this.keyword)

尽管做了上面的改进,还是觉得不太保险。若有第三种返回参数,还需要再加,这种情况还不可控。于是换了一种方法,通过请求百度地图提供的api来搜索。具体代码如下:

<template>
  <div>
    <div class="search-wrap">
      <div class="search">
        <input v-model="keyword" class="search-input" type="text" @input="search">
        <el-button type="primary" size="small" @click="handleSubmit">确认</el-button>
      </div>

      <!-- 检索结果 -->
      <div v-show="showResultFlag" class="search-result">
        <div v-for="(item, index) in results" :key="index" class="item" @click="handleSelect(item)">
          <p class="title">{{ item.name }}</p>
          <p class="address">{{ item.address }}</p>
        </div>
      </div>
      </div>
    </div>
    <baidu-map
      class="bm-view"
      ak="XXX" 
      :center="mapCenter"
      :zoom="mapZoom"
      :scroll-wheel-zoom="true"
      @ready="onReady"
      @click="getClickInfo"
    />
  </div>
</template>

<script>
import BaiduMap from 'vue-baidu-map/components/map/Map.vue'
const defaultInfo = {
  lng: 0,
  lat: 0,
  addressStr: '',
  title: '',
  province: '', // 省
  city: '', // 市
  district: '' // 区
}
export default {
  name: 'MapMaker',
  components: {
    BaiduMap
  },
  data() {
    return {
      ssq: {
        provinceName: '',
        cityName: '',
        districtName: ''
      },
      BMap: null,
      map: null,
      mapZoom: 15,
      mapCenter: { lng: 121.329402, lat: 31.228667 },
      keyword: '',
      searchResult: [], // 检索结果列表
      showResultFlag: true, // 控制是否展示搜索的结果
      selectInfo: Object.assign({}, defaultInfo)
    }
  },
  methods: {
  search() {
      const city = this.city || '北京市' // 最好有一个默认的城市,否则可能会有返回的数据为空的情况
      if (!this.keyword) {
        this.showResultFlag = false
      } else {
        this.showResultFlag = true
      }
      // 这里使用百度提供的api来搜索,搜索的关键词最好加一个encodeURIComponent方法(如下),不然在ie浏览器会变成乱码,报错。如果项目对ie浏览器不是硬性要求的话,可以不加。
      if (this.keyword && this.keyword.length > 0) {
        $.ajax({
          url: `https://api.map.baidu.com/place/v2/suggestion?query=${encodeURIComponent(this.keyword)}&region=${encodeURIComponent(city)
          }&city_limit=false&output=json&ak=xxxxxx`,
          type: 'GET',
          contentType: 'application/json;charset=utf-8',
          dataType: 'jsonp', // 这里要用jsonp的方式不然会报错
          success: (data) => {
            this.results = data.result
          }
        })
      }
    },
    // 地图初始化回调
    onReady({ BMap, map }) {
      this.BMap = BMap
      this.map = map
    },
    handleSelect(item) {
      const self = this
      console.log('item', item)
      this.city = item.city
      const { lng, lat } = item.location
      const point = new this.BMap.Point(lng, lat)
      const geoc = new this.BMap.Geocoder()
      geoc.getLocation(point, function(res) {
        console.log('res------------', res)
        const addString =
          res.addressComponents.province + res.addressComponents.city + res.addressComponents.district + title
        self.showResultFlag = false
        self.keyword = addString
        self.map.clearOverlays() // 清除地图上所有覆盖物
        self.map.addOverlay(new self.BMap.Marker({ lng, lat }))
        self.mapCenter.lng = lng
        self.mapCenter.lat = lat
        self.mapZoom = 18
        self.selectInfo = {
          lng,
          lat,
          addressStr: addString,
          title: title,
          province: res.addressComponents.province,
          city: res.addressComponents.city,
          district: res.addressComponents.district
        }
      })
    },
    handleSubmit() {
      // 我的百度地图是组件,在这一步触发父组件的方法提交数据
      this.$emit('submitAddressFun', this.selectInfo)
    },
    // 在地图上选取
    getClickInfo(e) {
      console.log(e)
      this.mapCenter.lng = e.point.lng
      this.mapCenter.lat = e.point.lat
      const BMapGL = this.BMap
      const map = this.map
      map.clearOverlays()
      const marker = new BMapGL.Marker(
        new BMapGL.Point(e.point.lng, e.point.lat)
      )
      map.addOverlay(marker)
      // 创建地理编码实例
      // eslint-disable-next-line no-undef
      const myGeo = new BMap.Geocoder()
      // 根据坐标逆解析地址
      // eslint-disable-next-line no-undef
      myGeo.getLocation(new BMap.Point(e.point.lng, e.point.lat), (result) => {
        console.log('打印result------', result)
        if (result) {
          // 我的代码其实是用的result.surroundingPois[0]的address,手动点击地图获取地址,总是没有输入的准确,导致手动获取的地址总是不完整,所以我就没用result.address,这里就仁者见仁,智者见智。
          // const surroundAdd = result.surroundingPois[0] // 这个是选取周围建筑地第一个
          // this.keyword = surroundAdd.address

          if (result.address) { // 会出现一种情况,就是返回的address是空的,这个时候就要自己拼接一下
            this.keyword = result.address
          } else {
            const ad = result.addressComponents
            this.keyword = ad.province + ad.city + ad.district + ad.street + ad.streetNumber
          }
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.map-maker-wrapper {
  position: relative;
}
.btn-confrim {
  width: 120px;
  height: 56px;
  line-height: 56px;
  background-color: #5ac9d4;
  border-radius: 8px;
  color: #ffffff;
  text-align: center;
}
.bm-view {
//   margin-top: 30px;
  width: 100%;
  height: calc(100vh - 88px);
}
.search-wrap {
  position: relative;
  width: 350px;
  box-sizing: border-box;
  padding: 0 32px;
  .search {
        z-index: 5;
        width: 450px;
        height: 30px;
        position: absolute;
        top: -66px;
        left: 30%;
    }

    .search input {
        float: left;
        width: 350px;
        height: 100%;
        border: 1px solid #30ccc1;
        padding: 0 8px;
        outline: none;
    }

    .search button {
        float: left;
        /*width: 20%;*/
        height: 100%;
        background: #30ccc1;
        border: 1px solid #30ccc1;
        color: #fff;
        outline: none;
    }
  .search-result {
    position: absolute;
    top: -34px;
    left: 30%;
    width: 406px;
    z-index: 5;
    background-color: #fff;
    padding: 0 32px;
    border-radius: 10px;
    max-height: 420px;
    overflow-y: scroll;
    .item {
      border-bottom: 1px solid #ebeef2;
    //   padding: 32px 0;
      &:last-child {
        border-bottom: none;
      }
      .title {
        font-size: 14px;
        font-weight: 600;
        color: #313233;
        margin: 10px 0 5px;
      }
      .address {
        font-size: 12px;
        font-weight: 400;
        color: #9ca5b3;
        margin: 5px 0 10px;
        // margin-top: 8px;
      }
    }
  }
}
</style>

安装引入百度地图可以看vue之百度地图的使用(一),这里记录的两种方法最大的区别就是搜索地址的方式不一样。尽管都能实现功能,但个人建议通过百度地图api去搜索更好。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值