vue-baidu-map-3x 使用记录

这篇具有很好参考价值的文章主要介绍了vue-baidu-map-3x 使用记录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在 Vue3 + TypeScript 项目中,为了采用 标签组件 的方式,使用百度地图组件,冲浪发现了一个开源库 ovo,很方便!喜欢的朋友记得帮 原作者 点下 star ~

vue-baidu-map-3xbaidu-map的vue3/vue2版本(支持v2.0、v3.0和webGl api)我全都有。同时也是vue2-baidu-map的文档https://map.heifahaizei.com/doc/index.html

目录

快速上手

全局注册

局部注册

注意事项

错误示例

正确示例

输入框搜索点位,并定位至该点位

实现效果

引入地图组件

为什么不采用 BmAutoComplete?

使用 BmControl 实现自定义控件

定义响应式变量

关于初始化变量的踩坑

添加地图初始化方法 ready

监听外部组件传入地址的监变化

ready 方法逻辑 

获取地址搜索结果列表

使用百度地图 API 检索跨域

获取搜索结果列表方法 

执行定位

使用 nextTick 修改数据

点位弹窗信息

展示搜索点位的周边点位弹窗

实现效果

引入地图组件

辐射圆、海量点组件

控制弹框在地图范围内显示

接收弹框组件的周边点位数据,并显示

【一个我很迷惑的报错】多个页面引用地图组件时,路由报错


快速上手

全局注册

一次性引入 百度地图组件库 的所有组件

import { createApp } from 'vue'
import App from './App.vue'
import BaiduMap from 'vue-baidu-map-3x'

const app = createApp(App);

app.use(BaiduMap, {
  // ak 是在百度地图开发者平台申请的密钥 详见 http://lbsyun.baidu.com/apiconsole/key */
  ak: '百度地图ak',
  // v:'2.0',  // 默认使用3.0
  // type: 'WebGL' // ||API 默认API  (使用此模式 BMap=BMapGL)
});
app.mount('#app');

局部注册

<template>
  <baidu-map class="map" ak="BaiduMapAK" v="3.0" type="API" :center="{lng: 116.404, lat: 39.915}" :zoom="15">
  </baidu-map>
</template>

<script setup>
import { BaiduMap } from 'vue-baidu-map-3x'
</script>

<style>
.map {
  width: 100%;
  height: 300px;
}
</style>

注意事项

  • 百度地图容器 必须 定义高度:BaiduMap 组件容器本身是一个空的块级元素,如果容器不定义高度,百度地图将渲染在一个高度为 0 不可见的容器内
  • 百度地图容器 必须 定义 center、zoom:没有设置 center 和 zoom 属性的地图组件是不进行地图渲染的。当 center 属性为合法地名字符串时例外,因为百度地图会根据地名自动调整 zoom 的值
  • 在 ready 中执行地图 API 加载后的代码,不能在 onMounted 中执行:由于百度地图 JS API 只有 JSONP 一种加载方式,因此 BaiduMap 组件及其所有子组件的渲染只能是异步的。因此,请使用在组件的 ready 事件来执行地图 API 加载完毕后才能执行的代码,不要试图在 vue 自身的生命周期中调用 BMap 类,更不要在这些时机修改 model 层

错误示例

<script setup>
import {ref,onMounted} from 'vue';

const center = ref({lng: 0, lat: 0});
const zoom = ref(3);

onMounted(() => {
  center.value.lng = 116.404;
  center.value.lat = 39.915;
  zoom.value = 15;
});
</script>

正确示例

<script setup>
import {ref,onMounted} from 'vue';

const center = ref({lng: 0, lat: 0});
const zoom = ref(3);

const handler = ({BMap, map}) => {
  console.log(BMap, map);
  center.value.lng = 116.404;
  center.value.lat = 39.915;
  zoom.value = 15;
}
</script>

输入框搜索点位,并定位至该点位

实现效果

二次封装地图组件:

  • 该组件可以被 编辑、查看、其他页面 进行引入
  • 该组件可以接收指定的值(地点名称、经纬度等等)
  • 点击 确认按钮 后,搜索显示结果列表
  • 点击 结果列表的某项 后,定位到该点,并让该点居中展示

接收搜索字段,显示搜索结果列表:

vue-baidu-map-3x 使用记录,ArcGIS,百度地图

点击结果列表,执行定位,展示点位信息:vue-baidu-map-3x 使用记录,ArcGIS,百度地图

引入地图组件

先来看看完整代码

    <baidu-map
      class="ths-map"
      :zoom="mapZoom"
      :center="mapCenter"
      @ready="ready"
    >
      <!-- 比例尺控件 -->
      <bm-scale anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-scale>
      <!-- 缩放控件 -->
      <bm-navigation anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-navigation>
      <!-- 定位控件 -->
      <bm-geolocation anchor="BMAP_ANCHOR_BOTTOM_RIGHT" :show-address-bar="true" :auto-location="true"></bm-geolocation>

      <!-- 自定义控件 -->
      <bm-control class="map-search-bm-control">
        <!-- 手写输入框 -->
        <div class="flex map-search-container">
          <el-input v-model="keyword" class="map-search-input" @input="getSearchList"></el-input>
          <el-button type="primary" class="map-search-btn" @click="getSearchList">
            搜索
          </el-button>
        </div>
        <!-- 搜索列表 -->
        <div v-if="searchListVisible" class="map-search-list">
          <div
            v-for="(elem, eIndex) of searchList"
            :key="eIndex"
            class="map-search-item"
            @click="performPositioning(elem)"
          >
            <p class="map-search-item-title">
              {{ elem.name }}
            </p>
            <p class="map-search-item-addr">
              {{ elem.address }}
            </p>
          </div>
        </div>
      </bm-control>

      <!-- 点 https://map.heifahaizei.com/doc/overlay/marker.html -->
      <bm-marker
        v-if="isShowSearchPoint"
        :position="{ lng: searchPoint.location.lng, lat: searchPoint.location.lat }"
        @click="spInfoWindow.show = true"
      >
      </bm-marker>

      <!-- 搜索点位弹窗 https://map.heifahaizei.com/doc/overlay/info-window.html#%E5%B1%9E%E6%80%A7 -->
      <bm-info-window
        :show="spInfoWindow.show"
        :title="spInfoWindow.name"
        :offset="{ width: 0, height: -24 }"
        :position="{ lng: spInfoWindow.location.lng, lat: spInfoWindow.location.lat }"
        :width="0"
        :max-width="300"
        @close="spInfoWindow.show = false"
        @open="spInfoWindow.show = true"
      >
        <!-- {{ spInfoWindow }} -->
        <!-- 搜索点位地址 -->
        <p class="sp-info-window-addr">
          {{ spInfoWindow.spName }}:<br />
          {{ spInfoWindow.spAddress }}
        </p>
        <div class="sp-info-window-header">
          <!-- 搜索点位名称 -->
          <!-- <span class="sp-info-window-name">{{ spInfoWindow.spName }}</span> -->
          <span class="sp-info-window-around" @click="infoWinGoAround"> 搜周边 </span>
        </div>
      </bm-info-window>
    </baidu-map>

 文章来源地址https://www.toymoban.com/news/detail-635123.html

为什么不采用 BmAutoComplete?

这个需求使用 官网组件 bm-auto-complete 能实现,不采用是基于以下几个原因:

  • UI 定制效果太差了,无法 深度定制 输入框样式(使用 el-input 组件会出现 bug,貌似只能采用原生 input 组件)
  • 控制 请求发送时机 不方便(文字发生变化直接就请求了,有的时候希望点了确认按钮再请求)
  • 无法自定义请求结果列表

vue-baidu-map-3x 使用记录,ArcGIS,百度地图

使用 BmControl 实现自定义控件

为了解决上一个问题,采用了 BmControl

定义响应式变量

关于初始化变量的踩坑

这些变量 尽量 一开始就写好数据结构:

  • 比如 mapCenter 里,一开始就应该定义 lng、lat,后面具体的值可以是 0 state.mapCenter = { lng: 0, lat: 0}
  • 如果直接初始化成 state.mapCenter = {},会导致发生不可预知的错误

当然这并不是绝对的:

  • 我最开始没初始化 单个点位 searchPoint 的对象结构时,没报错
  • 我最开始没初始化 点位信息弹窗 spInfoWindow 的对象结构时,就报错找不到 lng 属性了
    const state = reactive({
      // 地图缩放级别
      mapZoom: 11,
      // 地图中心点
      mapCenter: {
        lng: 113.88402,
        lat: 22.555259,
      },
      // 是否展示搜索点位
      isShowSearchPoint: false,
      // 搜索点位信息
      searchPoint: {
        lng: 0,
        lat: 0,
      } as any,
      // 搜索点位弹窗信息
      spInfoWindow: {
        show: false,
        spName: '',
        spAddress: '',
        location: {
          lng: 0,
          lat: 0,
        },
      } as any,
      // 搜索关键字
      keyword: '',
      // 搜索列表
      searchList: [] as any[],
      // 搜索列表是否可见
      searchListVisible: false,
    });

初始化方法可以在 ready 函数中执行,不能在 onMounted 中执行

    /**
     * 页面初始化
     */
    const initPage = () => {
      // 是否展示搜索点位
      state.isShowSearchPoint = false;
      // 搜索点位信息
      state.searchPoint = {} as any;
      // 搜索点位弹窗信息
      state.spInfoWindow = {
        show: false,
        spName: '',
        spAddress: '',
        location: {
          lng: 0,
          lat: 0,
        },
      };
      // 搜索列表
      state.searchList = [];
      // 搜索列表是否可见
      state.searchListVisible = false;
    };

添加地图初始化方法 ready

监听外部组件传入地址的监变化

外部传入的地址,会被赋值给 state 中的变量,防止 props 被修改

    watch(
      () => props.complaintsAddr,
      () => {
        state.keyword = props.complaintsAddr;
        // 关闭周边搜索弹框
        state.aroundDialogVisible = false;
      },
    );

ready 方法逻辑 

props.complaintsAddr 是供其他页面传入 地址 的字段:

  • 如果接收到了这个字段,则直接调用百度地图 API 接口,获取搜索结果列表,执行定位
  • 如果没接收到这个字段,则执行初始化,调整 state 中的变量,隐藏不该出现的内容
    const ready = async (e: any) => {
      if (props.complaintsAddr) {
        await getSearchList();
        for (const elem of state.searchList) {
          if (elem.address === props.complaintsAddr || elem.name === props.complaintsAddr) {
            performPositioning(elem);
            break;
          }
        }
      } else {
        // 页面初始化
        await initPage();
      }
    };

    onMounted(async () => {
      /*
       *  页面初始化
       * await initPage();
       */
    });

 

获取地址搜索结果列表

使用百度地图 API 检索跨域

 地点检索 | 百度地图API SDK

vue-baidu-map-3x 使用记录,ArcGIS,百度地图

本地调用百度接口,会出现跨域问题,这是正常的,使用 nginx 代理本地发送的请求

        location /mapapi/ {
            proxy_pass   http://api.map.baidu.com/;
           add_header Access-Control-Allow-Origin *;
        }

 

获取搜索结果列表方法 

    /**
     * 获取搜索列表
     */
    const getSearchList = async () => {
      state.searchList = [];
      try {
        const res = await getInputList(state.keyword, '宝安区');
        if (res.data.message === 'ok') {
          state.searchList = res.data?.results;
          // 展示搜索列表
          state.searchListVisible = true;
        }
      } catch (err) {
        console.error('地图 搜索列表 接口请求失败', err);
        state.searchList = [];
        state.searchListVisible = true;
      }
    };

执行定位

使用 nextTick 修改数据

单个点 BmMaker 组件,使用 v-if 进行控制,否则一开始没点搜索结果的时候,就会直接渲染

使用 nextTick,修改点位坐标数据、中心点数据、点位弹框信息,原因如下:

  • 如果不使用 nextTick,会导致 点位弹框信息 报错 —— 获取不到 img 这个 DOM 元素
  • 也就是说,点位弹框信息 必须在 点位存在 的时候,才能渲染

选择结果列表后,应该把选中的结果信息发出去,告诉外面使用地图的组件

    /**
     * 执行定位
     * @param elem 点位信息,必传
     * @param isCloseSearchList 是否关闭搜索列表,菲必传
     */
    const performPositioning = async (elem: any) => {
      // console.log('执行定位 ---', elem);

      // 隐藏列表
      state.searchListVisible = false;

      // 修改关键字信息
      state.keyword = elem.address ? elem.address : elem.name;
      // 更新外部组件的关键字信息
      emit('search-point-info', elem);

      // 渲染点位
      nextTick(() => {
        // 修改中心点坐标,把当前搜索点,设置为中心点
        state.mapCenter.lng = elem.location.lng;
        state.mapCenter.lat = elem.location.lat;

        // 修改搜索点位坐标
        state.searchPoint = elem;
        // 展示搜索点位
        state.isShowSearchPoint = true;
        console.log('搜索点位的经纬度 ---', state.searchPoint);

        // 设置点位弹窗信息
        showInfoWindow(elem);
      });
    };

 

点位弹窗信息

    /**
     * 展示点位弹窗
     * @param elem 点位信息
     */
    const showInfoWindow = (elem: any) => {
      // 设置点位弹窗信息
      state.spInfoWindow.spName = elem.name; // 标题
      state.spInfoWindow.spAddress = elem.address; // 地址
      state.spInfoWindow.location = elem.location; // 弹框坐标

      // 展示点位信息弹框
      state.spInfoWindow.show = true;

      // 修改搜索点位坐标
      state.searchPoint = elem;

      state.mapCenter = elem.location;

      console.log('展示点位弹窗 ---', state.spInfoWindow);
    };

展示搜索点位的周边点位弹窗

实现效果

  • 点击搜索点位的去周边后,出现弹框
  • 弹窗只能在地图中显示,不能在整个屏幕中显示
  • 搜索到周边点位后,地图绘制周边距离(辐射圆),并把所有点位进行打点

vue-baidu-map-3x 使用记录,ArcGIS,百度地图

 

 

引入地图组件

辐射圆、海量点组件

      <!-- 添加-多个点 https://map.heifahaizei.com/doc/overlay/point-collection.html -->
      <bm-point-collection
        :points="points"
        shape="BMAP_POINT_SHAPE_STAR"
        color="red"
        size="BMAP_POINT_SIZE_SMALL"
      >
      </bm-point-collection>

      <!-- 圆 https://map.heifahaizei.com/doc/overlay/circle.html -->
      <bm-circle
        :center="circlePath.center"
        :radius="circlePath.radius"
        stroke-color="blue"
        :stroke-opacity="0.5"
        :stroke-weight="2"
        :editing="false"
        :mass-clear="true"
      ></bm-circle>

 

控制弹框在地图范围内显示

el-dialog 只能在全局内显示,所以:手写 div 当弹框,让弹框跟地图点位同级,通过绝对定位实现

vue-baidu-map-3x 使用记录,ArcGIS,百度地图

接收弹框组件的周边点位数据,并显示

注意:辐射圆单位是 m,画太小了,页面就显示不出辐射圆了(……)

    /**
     * 地图多个点集合
     */
    const addPoints = (elems: any) => {
      const pointAll = [];
      for (const workSite of elems.workSiteResult) {
        const position = { lng: workSite.longitude, lat: workSite.latitude };
        pointAll.push(position);
      }

      state.points = pointAll;
      // 填充辐射圆半径
      state.circlePath.radius = elems.kilometerDistance * 1000;
      // 填充辐射圆中心坐标
      state.circlePath.center = elems.location;
    };

 

【一个我很迷惑的报错】多个页面引用地图组件时,路由报错

我在查看、编辑页都引用了地图组件,就会出现下面的报错

vue-baidu-map-3x 使用记录,ArcGIS,百度地图

后来发现,只要我把地图、地图组件内部的组件,再 cv 一份出来,分别引入到对应的页面,才能解决报错

如下所示,3 中的 edit、view 会引用地图组件,如果 3 中的 edit、view 同时引用了 1 或者同时引用了 2,那就会报错

3 中的 edit 引用 1,view 引用 2,就不会报错

vue-baidu-map-3x 使用记录,ArcGIS,百度地图

 

到了这里,关于vue-baidu-map-3x 使用记录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue 使用百度地图记录

    参考文档 https://lbsyun.baidu.com/index.php?title=jspopular3.0/guide/infowindow https://lbsyun.baidu.com/cms/jsapi/reference/jsapi_reference_3_0.html#a0b0 参考链接:https://api.map.baidu.com/library/MarkerClusterer/1.2/docs/symbols/BMapLib.MarkerClusterer.html 下载这个js

    2024年02月13日
    浏览(39)
  • ArcGIS Maps SDK for JavaScript系列之一:在Vue3中加载ArcGIS地图

    ArcGIS Maps SDK for JavaScript 是由 Esri 公司开发的一款用于构建交互式地图应用程序的 JavaScript 库。它提供了丰富的地图显示、分析和可视化功能,适用于各种场景。 目前,ArcGIS Maps SDK for JavaScript 提供两个主要版本:3.x 和 4.x。 ArcGIS Maps SDK for JavaScript 3.x 版本: 3.x 版本是 ArcGIS

    2024年02月13日
    浏览(51)
  • ArcGIS Maps SDK for JS(一):概述与使用

    ArcGIS Maps SDK for JavaScript(以前称为 ArcGIS API for JavaScript),是Esri(环球信息科技公司)开发的一款开发的一款基于JavaScript的webGIS开发工具,用于构建网络制图和空间分析应用程序。SDK 包含 JavaScript API、API 参考、文档、示例和其他资源,可帮助构建网络制图应用程序。截止到

    2024年02月09日
    浏览(36)
  • Baidu Comate 基于百度文心一言的智能编码助手

    本心、输入输出、结果 编辑:简简单单 Online zuozuo 地址:https://blog.csdn.net/qq_15071263 个人简介 : 简简单单Online zuozuo,目前主要从事 Java 相关工作,商业方向为 B、G 端

    2024年02月03日
    浏览(78)
  • 使用百度地图官方WEB API,提示APP服务被禁用了,可以访问 http://lbsyun.baidu.com/apiconsole/key# 查看自己的应用具体详情,或联系我们了解详情

    使用百度地图官方WEB API,显示APP服务被禁用了,可以访问 http://lbsyun.baidu.com/apiconsole/key# 查看自己的应用具体详情,或联系我们了解详情 笔者使用百度地图官方WEBDemo下载至本地进行测试,换上笔者的ak,运行代码游览器弹窗显示 相关代码 步骤1、重新创建应用,应用类型选择

    2024年02月12日
    浏览(118)
  • linux添加sht3x温湿度传感器驱动记录

           最近拿到一块imx6ull板子,上面有一颗温湿度传感器sht30,需要读取其数值。本人能力有限,自己写驱动还有一点困难,好在 linux内核里自带了很多器件的驱动,只需要找到相关的驱动文件根据要求修改一下设备树、添加进内核里编译就可以。         目前新版本的l

    2024年02月10日
    浏览(40)
  • ping www.baidu.com 所解析的ip是否为百度的真实ip?若不是,如何找到真实ip?

    一般情况下,dos命令ping域名会显示真实ip。 有些用户较多的网站,会启用CDN做 防护 (难找到真实IP) 或 加速 ,如baidu。 1、站长工具,多地ping的方式,响应ip不同 2、nslookup,返回地址为多个   1、查找dns历史解析记录(微步在线) 2、查找子域名 3、搜索引擎

    2024年02月13日
    浏览(44)
  • 在https://m.baidu.com/百度搜索框中输入文字点击搜索,出现如下错误:Message: element not interactable.

    问题: 开始学习selenium自动化测试,在https://m.baidu.com/的输入框中输入文字,点击搜索,但是找到输入框写入文字并点击按钮后,出现如下错误:Message: element not interactable. 解决办法: 在准备输入文字时,会先点击一下那个搜索框,所以捕获不到搜索框元素。所以在输入文字

    2024年02月13日
    浏览(31)
  • 使用了百度OCR,记录一下

    由于识别ocr有的频率不高,图片无保密性需求,也不想太大的库, 就决定还是用下api算了,试用了几家,决定用百度的ocr包,相对简单。 遇到的问题里面下列基本有提到:例如获取ID,KEY;例如安装库; 参考帖子:python+百度OCR的使用方法(踩坑+测试程序)_no module named \\\'ai

    2024年02月06日
    浏览(46)
  • 虚拟机中ping www.baidu.com提示【未知的名称或服务】,但是ping 百度的IP 可以ping通的问题解决方案

    1.遇到的问题描述:          在虚拟机中ping www.baidu.com,提示【未知的名称或者服务】           在本机中ping www.baidu.com,可以ping通           在虚拟机中尝试ping 百度的IP发现也可以ping通 这种情况,是由于虚拟机的DNS没有配置好造成的 2.解决方案一:         2.1 现

    2024年04月14日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包