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

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

vue-baidu-map-3xbaidu-map的vue3/vue2版本(支持v2.0、v3.0和webGl api)我全都有。同时也是vue2-baidu-map的文档icon-default.png?t=N6B9https://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>

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

实现效果

二次封装地图组件:

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

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

点击结果列表,执行定位,展示点位信息:

引入地图组件

先来看看完整代码

    <baidu-mapclass="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"><divv-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-markerv-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>

 

为什么不采用 BmAutoComplete?

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

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

使用 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

本地调用百度接口,会出现跨域问题,这是正常的,使用 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);};

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

实现效果

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

 

 

引入地图组件

辐射圆、海量点组件

      <!-- 添加-多个点 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 当弹框,让弹框跟地图点位同级,通过绝对定位实现

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

注意:辐射圆单位是 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;};

 

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

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

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

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

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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/23758.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用LLM插件从命令行访问Llama 2

大家好&#xff0c;最近的一个大新闻是Meta AI推出了新的开源授权的大型语言模型Llama 2&#xff0c;这是一项非常重要的进展。Facebook最初的LLaMA模型于今年2月发布&#xff0c;掀起了开源LLM领域的创新浪潮——从微调变体到从零开始的再创造。 如果在Llama 2版本发布之日&a…

《面试1v1》ElasticSearch 和 Lucene

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…

DLA 神经网络的极限训练方法:gradient checkpointing

gradient checkpointing 一般来说&#xff0c;训练的过程需要保存中间结果&#xff08;不管是GPU还是CPU&#xff09;。前向传播根据输入(bottom_data)计算输出(top_data)&#xff0c;后向传播由top_diff计算bottom_diff&#xff08;如果某个变量打开梯度进行训练的话&#xff…

Vue 动态引入外部js文件

场景 最近在做项目优化时&#xff0c;发现一个特殊依赖&#xff0c;全局只有一个页面会用到。这个依赖很大&#xff0c;而且这个页面极少有人会打开&#xff08;隐藏页&#xff0c;留给开发或交付人员调试使用的&#xff09;。 那么我们考虑通过引入外部js的形式来处理&#…

5个顶级的开源有限元分析软件

每当我参加数值分析课程的教学时&#xff0c;都会回顾有限元方法的基础知识&#xff0c;很自然地就会出现使用哪种软件的问题。 以下讨论基于三个基本考虑&#xff1a; 在实际应用中&#xff0c;很少有人从头开始编写 FEM 代码。商业 FEM 软件通常在某些预定义的情况下非常易于…

使用 Habana Gaudi2 加速视觉语言模型 BridgeTower

&#x1f917; 宝子们可以戳 阅读原文 查看文中所有的外部链接哟&#xff01; 在对最先进的视觉语言模型 BridgeTower 进行微调时&#xff0c;使用 Optimum Habana v1.6&#xff0c; Habana Gaudi2 可以达到 近 3 倍于 A100 的速度。硬件加速的数据加载以及 fast DDP 这两个新特…

luajit 使用 clang编译的坑

为了尝试将LuaJIT接入虚幻Lua插件之中&#xff0c;需要预编译LuaJIT链接库&#xff0c;在桌面平台问题不大, 主要是移动平台&#xff0c;涉及跨平台编译&#xff0c;因为对跨平台编译具体细节没有系统研究&#xff0c;这里先记录一下跨平台编译LuaJIT的主要过程 由于官方提供的…

Pandas操作Excel

Pandas 是 Python 语言的一个扩展程序库&#xff0c;用于数据分析。 菜鸟教程&#xff1a;https://www.runoob.com/pandas/pandas-tutorial.html 读取Excel pd.read_excel(path,sheet_name,header) path&#xff1a;excel文件路径sheet_name&#xff1a;读取的sheet&#xff0…

3.netty和protobuf

1.ChannelGroup可以免遍历由netty提供,覆盖remove方法即可触发删除channel\ 2.群聊私聊 13.群聊私聊简单原理图 3.netty心跳检测机制,客户端对服务器有没有读写(读,写空闲) //IdleStateHandler(3,5,7,TimeUnite.SECONDS)是netty提供的检测状态的处理器,也加到pipeline,读,写,…

【新版系统架构补充】-嵌入式软件

嵌入式软件 嵌入式软件是指应用在嵌入式计算机系统当中的各种软件&#xff0c;除了具有通用软件的一般特性&#xff0c;还具有一些与嵌入式系统相关的特点&#xff0c;包括&#xff1a;规模较小、开发难度大、实时性和可靠性要求高、要求固化存储。 嵌入式软件分类&#xff1…

react Ref 的基本使用

类组件中使用ref 在类组件中&#xff0c;你可以使用createRef来创建一个ref&#xff0c;并将它附加到DOM元素或类组件实例上。使用ref允许你在类组件中访问和操作特定的DOM元素或类组件实例。 下面是在类组件中使用ref的步骤&#xff1a; 引入React和createRef&#xff1a; …

浅析 C 语言的共用体、枚举和位域

前言 最近在尝试阅读一些系统库的源码&#xff0c;但是其中存在很多让我感到既熟悉又陌生的语法。经过资料查阅&#xff0c;发现是 C 语言中的共用体和位域。于是&#xff0c;趁着课本还没有扔掉&#xff0c;将一些相关的知识点记录在本文。 文章目录 前言共用体 (union)枚举…

Tomcat 的内存配置

修改 Tomcat 的内存配置&#xff0c;你需要调整 Tomcat 的 Java 虚拟机&#xff08;JVM&#xff09;参数。具体来说&#xff0c;你需要修改 catalina.sh&#xff08;Linux/macOS&#xff09;或 catalina.bat&#xff08;Windows&#xff09;脚本中的 JAVA_OPTS 变量。以下是一般…

【LeetCode 算法】Merge Two Sorted Lists 合并两个有序链表

文章目录 Merge Two Sorted Lists 合并两个有序链表问题描述&#xff1a;分析代码迭代递归 Tag Merge Two Sorted Lists 合并两个有序链表 问题描述&#xff1a; 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 两个链表的…

GNN code Tips

1. 重置label取值范围 problem: otherwise occurs IndexError: target out of bounds # reset labels value range, otherwise occurs IndexError: target out of bounds uni_set torch.unique(labels) to_set torch.tensor(list(range(len(uni_set)))) labels_reset label…

网络开发-IO模型

基本概念 I/O即数据的读取&#xff08;接收&#xff09;或写入&#xff08;发送&#xff09;操作 通常用户进程中的一个完整I/O分为两个阶段 用户进程空间<-->内核空间内核空间<-->设备空间&#xff08;磁盘、网卡等&#xff09; I/O分为内存I/O、网络I/O和磁盘…

【编程】典型题目:寻找数组第K大数(四种方法对比)

【编程】典型题目&#xff1a;寻找数组第K大数&#xff08;四种方法对比&#xff09; 文章目录 【编程】典型题目&#xff1a;寻找数组第K大数&#xff08;四种方法对比&#xff09;1. 题目2. 题解2.1 方法一&#xff1a;全局排序&#xff08;粗暴&#xff09;2.2 方法二&#…

2023年第二届网络安全国际会议(CSW 2023)

会议简介 Brief Introduction 2023年第二届网络安全国际会议(CSW 2023) 会议时间&#xff1a;2023年10月13日-15日 召开地点&#xff1a;中国杭州 大会官网&#xff1a;www.cybersecurityworkshop.org 2023年第二届网络安全国际会议(CSW 2023)由杭州电子科技大学&#xff0c;国…

123.买卖股票的最佳时机3

目录 一、题目 二、分析代码 一、题目 123. 买卖股票的最佳时机 III - 力扣&#xff08;LeetCode&#xff09; 二、分析代码 class Solution { public:int maxProfit(vector<int>& prices) {//0表示没有操作//1表示第1次买入&#xff0c;2表示第1次卖出//3表示第2…

用html+javascript打造公文一键排版系统11:改进单一附件说明排版

一、用htmljavascript打造公文一键排版系统10中的一个bug 在 用htmljavascript打造公文一键排版系统10&#xff1a;单一附件说明排版 中&#xff0c;我们对附件说明的排版函数是&#xff1a; function setAtttDescFmt(p) {var t p;var a ;if (-1 ! t.indexOf(:))//是半角冒…