• Vue中引入百度地图(实现缩放,标记,信息窗)


    背景:在使用Vue做项目的时候,需要使用百度地图,使用了 vue-baidu-map插件

    实现的功能包括:地图的缩放,动态比例尺,动态设置地图中心点,根据经纬度在地图上进行标点,点击标记点打开信息窗口展示详情

    开工之前需要在项目中安装 ` vue-baidu-map` 的依赖

    npm install vue-baidu-map --save

    1.引入方式

    • 可以在 app.js 中全局引入(如果不是每个组件中都使用此组件不推荐全局引入)
    import BaiduMap from 'vue-baidu-map'
    
    Vue.use(BaiduMap, {
        /*  需要你在百度开放平台上注册,并申请ak */
      /*  项目上线时,记得要使用公司信息注册的ak  */
    ak:'YOUR_APP_KEY'
    })
    • 局部引入,引入方式与全局引入不同,需要在node_modules/vue-baidu-map/components 里面找到需要的组件

        注意:局部引入要在 `<baidu-map ak=''></baidu-map>`中声明ak属性

    //项目中引入使用百度地图的组件
    import BaiduMap from 'vue-baidu-map/components/map/Map.vue'    // 百度地图组件
    import BmScale from 'vue-baidu-map/components/controls/Scale'   // 比例尺组件
    import BmNavigation from 'vue-baidu-map/components/controls/Navigation'  // 缩放组件 
    import BmMarker from 'vue-baidu-map/components/overlays/Marker'  // 标记点的组件
    import BmLabel from 'vue-baidu-map/components/overlays/Label'    // 标签组件,展示在标记点中的数字
    import BmInfoWindow from 'vue-baidu-map/components/overlays/InfoWindow'  // 信息窗体
    
    // 组件的注册
    export default {
        components: {
            BaiduMap,
            BmScale,
            BmNavigation,
            BmMarker,
            BmInfoWindow,
            BmLabel
          },  
    }

    2.在组件中的使用,代码如下

    <baidu-map
                class="bm-view"
                :center="center"   // 动态设置中心点,center数据格式 => center:{lng:116.404,lat:39.915},可根据定位到不同的城市,动态改变值
                :zoom="zoom"    //  地图显示比例尺的大小,必须定义,有1~19个级别
                @ready="handler"   //  地图API加载完毕后执行的代码
                :scroll-wheel-zoom="true"   //  鼠标滚轮控制缩放
                :mapClick="false"       //  禁止点击景点弹出信息窗体,自定义的除外
                ak="YOUR_APP_KEY"       //  你申请的ak值
              >
                <!-- 比例尺控件,注册此组件才会在地图上显示比例尺 -->
                <bm-scale anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-scale>
                <!-- 缩放控件,注册此组件才会显示拖放进度 -->
                <bm-navigation anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-navigation>
                <div v-for="(marker, index) in markers" :key="marker.id">
             <!-- 标记点组件 -->
                  <bm-marker
                    :position="{ lng: marker.lng, lat: marker.lat }"
                    :title="marker.servestationname"
                    @click="infoWindowOpen(marker)"
                  >
              <!-- 信息窗体组件 -->
                    <bm-info-window
                      :title="marker.servestationname"
                      :position="{ lng: marker.lng, lat: marker.lat }"
                      :show="marker.showFlag"
                      @close="infoWindowClose(marker)"
                    >
                      <p>
                        {{ marker.servestationaddress }}
                      </p>
                      <p>服务车型:{{ marker.brandandcartype }}</p>
                      <p>联系人:{{ marker.handler }}</p>
                      <p>联系热线:{{ marker.phone }}</p>
                    </bm-info-window>
              <!-- 标签组件 -->
                    <bm-label
                      :content="index + 1 + ''"
                      :labelStyle="{
                        color: '#fff',
                        fontSize: '12px',
                        background: 'rgba(0, 0, 0, 0)',
                        borderColor: 'rgba(0, 0, 0, 0)',
                      }"
                      :offset="{  index >= 9 ? 0 : 4, height: 2 }"
                    />
                  </bm-marker>
                </div>
              </baidu-map>
    
    export default {
         data() {
        return {
          center: { lng: null, lat: null },
          zoom: 13,
          // 地图标记点数据
          markers: [
              {
               lng: 116.405,
               lat: 39.901,
               showFlag: false, //flag放在每一条数据里
             },
             {
               lng: 116.404,
               lat: 39.9,
               showFlag: false,
             },
          ]
        }
      },
        methods: {
            // 地图初始化完成回调
            handler({ BMap, map }) {
              this.center.lng = 116.404
              this.center.lat = 39.915
            },
            // 关闭标记详情
            infoWindowClose(marker) {
              marker.showFlag = false
            },
            // 打开标记详情
            infoWindowOpen(marker) {
              marker.showFlag = !marker.showFlag
            },
        }
    }
    View Code

    3.总结使用过程中遇见的问题

      这几个问题是来自组件文档的温馨提示,已亲测

    • BaiduMap 组件容器本身是一个空的块级元素,如果容器不定义高度,百度地图将渲染在一个高度为 0 不可见的容器内。
    • 没有设置 centerzoom 属性的地图组件是不进行地图渲染的。当center 属性为合法地名字符串时例外,因为百度地图会根据地名自动调整 zoom 的值。

        

    • 由于百度地图 JS API 只有 JSONP 一种加载方式,因此 BaiduMap 组件及其所有子组件的渲染只能是异步的。因此,请使用在组件的 ready 事件来执行地图 API 加载完毕后才能执行的代码,不要试图在 vue 自身的生命周期中调用 BMap 类,更不要在这些时机修改 model 层。

      现在总结下本次遇见的问题

    • 第一次在项目中使用,所以组件内引入组件有点晕,在经过一番百度之后,发现需要去依赖中找路径,和你需要的各个组件;每个功能都是一个组件!!!
    • 缩放组件问题,注册完成后,鼠标滚轮不能进行缩放,问题是要在 `<baidu-map>` 标签上配置 `:scroll-wheel-zoom="true"`
    • 比例尺,缩放组件的 anchor属性是配置元素在地图上显示的位置,参数详见文档
    • 关于给你经纬度信息,如何在地图上标记出来的问题,这里需要使用 marker 组件,因为不是一个标记点,需要渲染很多标记点,所以会出现很多问题

      ① 在bm-marker中使用v-for循环,但是bm-info-window只会创建一个

      方案:在 marker 组件的外面套一层 div,使用 v-for 在上面进行渲染

      ② 创建的出来的标记点个数不固定,怎么按序号展示呢?

      方案:这里需要使用 baidu-map 提供的 Label 组件,在这里需要给组件提供内容,样式,展示的偏移位置,用到的属性为:content,labelStyle,offset

      ③ 创建的出来的标记点,点击怎么会显示当前城市的详情呢?

      方案:这里需用 bm-info-window 组件,组件的标签内写需要的内容,该组件的 title 属性为信息窗的标题,可动态写入;组件的 show 属性控制显示/隐藏,position属性控制窗体位置

      ④在切换多个城市坐标时,标记点 根据上面 代码中的 markers 数据动态渲染,再点击标记点时,信息窗不能弹出

      问题排查:经过调试,发现点击事件可以触发,可以拿到最新的 markers 数据,但是事件传参的对象确是第一次的数据,疑惑?这应该是dom没有更新,看到外层的 v-for 渲染时,为了偷懒,key属性的值用的是index,切换坐标时,重新渲染的标记点的key值相同,所以 虚拟dom 的惰性触发,这里改成 id就解决啦!

      ⑤ 在自定义信息窗样式时,要写在全局样式中

    • 下面奉上比例尺级别对应的数据

             

    经过一路的踩坑,终于完成啦!

        

       传送门:vue-baidu-map中文文档

  • 相关阅读:
    2022省选前集训
    牛客挑战赛57总结
    Atcoder做题总结
    CR775总结
    卡特兰猜想的一个弱化形式
    Jinja2实现模板高度自定义
    Harbor仓库安装使用cfssl工具生成证书
    odoo15 视频聊天打不开摄像头及麦克风问题解决
    整合SSM
    力扣332题(重新安排行程)
  • 原文地址:https://www.cnblogs.com/spaortMan/p/13932126.html
Copyright © 2020-2023  润新知