vue-baidu-map实现详细地址搜索下拉框

952 阅读1分钟

1、前言

在PC端项目中,表单总是会有输入详细地址的情况,输入的详细地址又需要带上经纬度,如果借助百度/腾讯/高德开放接口去实现,但是弊端很明显

  • 第一个要解决浏览器跨域问题,
  • 第二个后台做代理转发,
  • 第三个接口每日超出访问次数需收费。

作为白嫖怪的我们,怎么能容忍这种收费情况的发生???

1662087928784.png

所以有了下面的解决方案

效果为: 10.gif

2、核心代码

核心思路是借助 vue-baidu-map 插件实现的

npm install vue-baidu-map
yarn add vue-baidu-map
"vue-baidu-map": "^0.21.22",

MySearchAddress 文件

image.png

MySearchAddress/components/MyBaiduMap.vue 文件

<!--
 * @Author: Null
 * @Date: 2022-06-23 08:38:47
 * @Description: 地图
-->
<template>
  <div class="BaiduMap">
    <baidu-map
      :scroll-wheel-zoom="true"
      :center="center"
      :zoom="zoom"
      :continuous-zoom="true"
      :double-click-zoom="true"
    >
      <bm-view v-show="['searchMap','map'].includes(customizedAttrs.type)" class="BaiduMap-map" />
      <bm-local-search
        v-show="['searchMap','search'].includes(customizedAttrs.type)"
        v-bind="customizedAttrs"
        v-on="$listeners"
      />

      <!-- 定位 -->
      <bm-geolocation anchor="BMAP_ANCHOR_BOTTOM_RIGHT" :show-address-bar="true" :auto-location="true" />

      <!-- 在右上角加入缩放控件  -->
      <!-- <bm-navigation :enable-geolocation="true" anchor="BMAP_ANCHOR_BOTTOM_RIGHT" /> -->
    </baidu-map>
  </div>
</template>

<script>
// 参考文档:https://dafrok.github.io/vue-baidu-map/#/zh/search/local-search
export default {
  name: 'MyBaiduMap',
  // 不希望组件的根元素继承特性
  inheritAttrs: false,
  data () {
    return {
      center: { lng: 116.404, lat: 39.915 }, // 北京
      zoom: 3
    }
  },
  computed: {
    customizedAttrs () {
      const obj = {
        // type: 'searchMap', // searchMap 表示有搜索下拉框的地图 ; search 表示只有搜索下拉框;  map表示只有地图
        location: '深圳', // String, Point, None 	location表示检索区域,其类型可为空、坐标点或城市名称的字符串。当参数为空时,检索位置由当前地图中心点确定,且搜索结果的标注将自动加载到地图上,并支持调整地图视野层级;当参数为坐标时,检索位置由该点所在位置确定;当参数为城市名称时,检索会在该城市内进行。
        keyword: '附近', // String, Array 搜索关键字。当keyword为数组时将同时执行多关键字的查询,最多支持10个关键字
        selectFirstResult: false, // 是否选择第一个检索结果
        forceLocal: true, // 表示是否将搜索范围约束在当前城市
        panel: true, // 是否选展现检索结果面板
        pageCapacity: 3, // 设置每页容量,取值范围:1 - 100,对于多关键字检索,每页容量表示每个关键字返回结果的数量(例如当用2个关键字检索时,实际结果数量范围为:2 - 200)。此值只对下一次检索有效
        autoViewport: true // 检索结束后是否自动调整地图视野。
      }
      const { type } = this.$attrs
      // searchMap 表示有搜索下拉框的地图 ; search 表示只有搜索下拉框
      obj.type = (type && ['searchMap', 'search', 'map'].includes(type)) ? type : 'searchMap'
      console.log('obj======>', obj)
      return Object.assign(obj, this.$attrs)
    }
  }
}
</script>

<style lang="scss" scoped>
.BaiduMap {
  @extend %card;
  width: $baiduMapSearchBoxWidth;
  &-map {
    width: 100%;
    height: $baiduMapSearchBoxWidth;
  }
}
</style>

MySearchAddress/index.vue 文件

<!--
 * @Author: Null
 * @Date: 2022-06-23 08:38:47
 * @Description: 地址搜索下拉框
-->
<template>
  <div class="MySearchAddress">
    <div class="MySearchAddress-searchBox" flex="cross:center main:center">
      <el-input v-model="bKeyword" class="MySearchAddress-searchBox__input" clearable />
      <MyButton :icon="showMap? 'el-icon-arrow-up':'el-icon-arrow-down'" @click="showMap = !showMap" />
    </div>
    <div v-show="bKeyword && showMap" class="MySearchAddress-map">
      <MyBaiduMap
        :type="type"
        :location="bLocation"
        :keyword="bKeyword"
        @resultshtmlset="resultshtmlset"
        @searchcomplete="searchcomplete"
        @markersset="markersset"
        @infohtmlset="infohtmlset"
      />
    </div>
  </div>
</template>

<script>
export default {
  name: 'MySearchAddress',
  components: {
    MyBaiduMap: () => import('./components/MyBaiduMap.vue'),
    MyButton: () => import('@/components/MyButton/index.vue')
  },
  props: {
    // String, Point, None 	location表示检索区域,其类型可为空、坐标点或城市名称的字符串。当参数为空时,检索位置由当前地图中心点确定,且搜索结果的标注将自动加载到地图上,并支持调整地图视野层级;当参数为坐标时,检索位置由该点所在位置确定;当参数为城市名称时,检索会在该城市内进行。
    location: {
      type: [String, Object],
      default: '深圳龙岗'
    },
    // String, Array 搜索关键字。当keyword为数组时将同时执行多关键字的查询,最多支持10个关键字
    keyword: {
      type: [String, Array],
      default: '街道'
    },
    // searchMap 表示有搜索下拉框的地图 ; search 表示只有搜索下拉框;  map表示只有地图
    type: {
      type: String,
      default: 'searchMap'
    }
  },
  data () {
    return {
      bKeyword: '',
      showMap: true // 是否展示地图
    }
  },
  computed: {
    bLocation () {
      return this.location || '深圳'
    }
  },
  watch: {
    keyword: {
      handler (newVal) {
        if (newVal) {
          console.log('获取得到新值====>', newVal)
          this.bKeyword = newVal
        }
      },
      immediate: true
    }
  },
  methods: {
    /**
     * @description: 结果列表添加完成后的回调函数
     * @param {*} ele
     * @return {*}
     */
    resultshtmlset (ele) {
      console.log('结果列表添加完成后的回调函数=====>', ele)
    },

    /**
     * @description: 检索完成后的回调函数。如果是多关键字检索,回调函数参数返回一个LocalResult的数组,数组中的结果顺序和检索中多关键字数组中顺序一致
     * @param {*} ele
     * @return {*}
     */
    searchcomplete (ele) {
      console.log('检索完成后的回调函数=====>', ele)
    },

    /**
     * @description: 标注添加完成后的回调函数
     * @param {*} ele
     * @return {*}
     */
    markersset (ele) {
      console.log('标注添加完成后的回调函数=====>', ele)
    },

    /**
     * @description: 标注气泡内容创建后的回调函数
     * @param {*} ele
     * @return {*}
     */
    infohtmlset (ele) {
      console.log('标注气泡内容创建后的回调函数=====>', ele)
      this.bKeyword = ele.address
    }
  }
}
</script>

<style lang="scss" scoped>
.MySearchAddress {
  position: relative;
  width: $baiduMapSearchBoxWidth;
  &-searchBox {
    margin-bottom: 4px;
  }
  &-map {
    width: 100%;
    position: absolute;
    background: #fff;
    z-index: 10;
  }
}
</style>

页面中使用

<MySearchAddress
   :location="baiduLocation"
   :keyword="baiduStreetDetail"
/>

// 百度地图location
baiduLocation: '',
baiduStreetDetail: '平湖街道乾龙物流园',

参数返回

image.png

【补充】如果有什么不理解的,请看源码,源码地址在上方

完结散花...