react如何引用(按需加载)百度地图,并结合and组件化封装

1.技术选项:

vite+react+antdesign

load-script

2.实现思路:

1.按需加载如何实现?

  要实现按需加载就不能直接在项目的入口文件这种地方去通过script标签引入,这里使用load-script封装了一个加载百度地图的Bmap.js方法,实现动态的插入script脚本。

根目录下创建Bmap.js文件

import _loadScript from 'load-script';export function Map(url) {return new Promise((resolve, reject) => {_loadScript(url, (error, script) => {if (error) {return reject(error);}console.log('====================================');console.log(script);console.log('====================================');resolve(script);});});
}export default function loadBMap() {return new Promise(function(resolve, reject) {if (typeof BMap !== 'undefined') {resolve(BMap);return true;}window.onBMapCallback = function() {resolve(BMap);};let script = document.createElement('script');script.type = 'text/javascript';script.src ='https://api.map.baidu.com/api?v=3.0&ak=自己的';script.onerror = reject;document.head.appendChild(script);});
}
2.初始化加载地图(注意事项)

要初始化加载地图,我们需要确保的时候,在页面绘制完,或者弹框加载完成之后再去调用初始化的方法,否则就会报错。

报错示例:

Cannot read properties of undefined (reading  kc )

封装示例图

3.map.js脚本实现如下:

// 加载百度地图
export function LoadBaiduMapScript() {console.log("百度地图脚本初始化ing----------------");const BMap_URL ="https://api.map.baidu.com/api?v=3.0&ak=换成自己的&callback=onBMapCallback";return new Promise((resolve, _reject) => {// 如果已加载直接返回if (typeof BMap !== "undefined") {resolve(BMap);return true;}// 百度地图异步加载回调处理window.onBMapCallback = function () {console.log("百度地图脚本初始化成功...");resolve(BMap);};// 插入script脚本const scriptNode = document.createElement("script");scriptNode.setAttribute("type", "text/javascript");scriptNode.setAttribute("src", BMap_URL);document.body.appendChild(scriptNode);});
}

React实现代码如下:

注意:new BMap 可能会爆红 不用管,不影响使用

地图实例,标记示例,手掌选择实例使用useRef存储吗,使用useState存储会导致内容重新渲染,造成初始化失败

import { Modal, Button, message, Input, Spin } from "antd";
import {useState,forwardRef,useImperativeHandle,useEffect,useRef,
} from "react";
import positionIcon from "@/assets/images/position.png";
import { LoadBaiduMapScript } from "./map";
import "./index.less";interface MapPropsType {onConfirm: (val) => void;
}const MapChoice = forwardRef((props: MapPropsType, ref) => {const { Search } = Input;const [isModalOpen, setIsModalOpen] = useState(false);const [searchValue, setSearchValue] = useState<string>("");const [loading, setLoading] = useState<boolean>(false);const [address, setAddress] =useState<string>("河南省郑州市二七区建设东路48号");const [lon, setLon] = useState<number>(113.65);const [lat, setLat] = useState<number>(34.76);// 使用 ref 存储地图相关对象(避免状态异步问题)const mapRef = useRef<any>(null);const pointRef = useRef<any>(null);const markerRef = useRef<any>(null);const showModal = () => {setIsModalOpen(true);};const handleOk = () => {setIsModalOpen(false);const data = { address, lon, lat };props.onConfirm(data); // 回调方式};const handleCancel = () => {setIsModalOpen(false);};useImperativeHandle(ref, () => ({showModal,handleOk,handleCancel,}));useEffect(() => {if (!isModalOpen) return;const init = async () => {await LoadBaiduMapScript();initMap({});await browserPosition();};init();}, [isModalOpen]);// 初始化地图const initMap = (record: any) => {const currentAddress = record.address || address || "郑州市";const currentLon = record?.coordinates?.lon ?? lon;const currentLat = record?.coordinates?.lat ?? lat;// 创建地图实例(使用 ref 存储)const mapInstance = new BMap.Map("container");const pointInstance = new BMap.Point(currentLon, currentLat);const myIcon = new BMap.Icon(positionIcon, new BMap.Size(23, 25));const markerInstance = new BMap.Marker(pointInstance, myIcon);// 存储到 refmapRef.current = mapInstance;pointRef.current = pointInstance;markerRef.current = markerInstance;// 初始化地图设置mapInstance.centerAndZoom(pointInstance, 15);mapInstance.enableScrollWheelZoom();mapInstance.addOverlay(markerInstance);// 更新状态setAddress(currentAddress);setLon(currentLon);setLat(currentLat);// 绑定点击事件mapInstance.addEventListener("click", (e: any) => {const clickedPoint = new BMap.Point(e.point.lng, e.point.lat);mapInstance.centerAndZoom(clickedPoint, 15);pointRef.current = clickedPoint;// 逆地理编码获取地址const gc = new BMap.Geocoder();gc.getLocation(clickedPoint, (rs: any) => {if (rs?.address) {setAddress(rs.address);setLon(e.point.lng);setLat(e.point.lat);upInfoWindow(rs.address, e.point.lng, e.point.lat);}});});// 初始信息窗口upInfoWindow(currentAddress, currentLon, currentLat);};// 更新信息窗口const upInfoWindow = (address: string, lon: number, lat: number) => {if (!mapRef.current || !pointRef.current) return;const opts = {width: 250,height: 120,title: "经纬度",};const word = `<div>地址:${address}</div><div>经度:${lon}</div><div>纬度:${lat}</div>`;const infoWindow = new BMap.InfoWindow(word, opts);mapRef.current.openInfoWindow(infoWindow, pointRef.current);markerRef.current.addEventListener("click", () => {mapRef.current.openInfoWindow(infoWindow, pointRef.current);});};// 地址搜索const handleSearch = () => {if (!searchValue?.trim()) {message.warning("搜索框不能为空");return;}const myGeo = new BMap.Geocoder();myGeo.getPoint(searchValue.trim(), (point: any) => {if (point) {mapRef.current.centerAndZoom(point, 15);pointRef.current = point;setLon(point.lng);setLat(point.lat);const gc = new BMap.Geocoder();gc.getLocation(point, (rs: any) => {if (rs?.address) {setAddress(rs.address);upInfoWindow(rs.address, point.lng, point.lat);}});} else {message.warning("您选择的地址没有解析到结果!");}});};// 浏览器定位const browserPosition = async () => {setLoading(true);const geolocation = new BMap.Geolocation();geolocation.getCurrentPosition(async (r: any) => {if (r?.point) {const point = new BMap.Point(r.point.lng, r.point.lat);mapRef.current.centerAndZoom(point, 15);pointRef.current = point;const gc = new BMap.Geocoder();gc.getLocation(point, (rs: any) => {if (rs?.address) {setAddress(rs.address);setLon(r.point.lng);setLat(r.point.lat);upInfoWindow(rs.address, r.point.lng, r.point.lat);}});} else {message.error("定位失败,请手动输入经纬度");}setLoading(false);});};return (<><div className="flex items-center"><div className="mr-2">位置</div><Button type="primary" onClick={showModal}>唤醒地图</Button></div><Modaltitle="地图选择"open={isModalOpen}onOk={handleOk}onCancel={handleCancel}width={1000}okText={"确认"}cancelText={"关闭"}><Spin spinning={loading}><Searchplaceholder="请输入地址"value={searchValue}onChange={(e) => setSearchValue(e.target.value)}onSearch={handleSearch}style={{ width: "40%" }}/><div id="container" className="positionbox"></div></Spin></Modal></>);
});export default MapChoice;

less样式代码

.positionbox {width: 100%;height: 64vh;margin-top: 20px;}

实现效果如下

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

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

相关文章

LeetCode 第31~33题

目录 LeetCode 第31题&#xff1a;下一个排列 LeetCode 第32题&#xff1a;最长有效括号 LeetCode 第33题&#xff1a;搜索旋转排序数组 LeetCode 第31题&#xff1a;下一个排列 题目描述 整数数组的一个排列就是将所有成员以序列或线性顺序排列。例如arr[1,2,3]&#xff0c;以…

虚拟现实--->unity学习

前言&#xff1a;这学期劳动课选了虚拟现实&#xff0c;其中老师算挺认真的&#xff0c;当然对一些不感兴趣的同学来说是一种折磨&#xff0c;我对这个unity的学习以及后续的虚幻引擎刚开始连基础的概念都没有&#xff0c;后面渐渐也是滋生了一些兴趣&#xff0c;用这篇博客记录…

在Trae中设置Python解释器版本

Python 是一种广泛使用的高级编程语言&#xff0c;因其简洁易读的语法和强大的功能而备受欢迎。随着 Python 的不断发展&#xff0c;多个版本相继发布&#xff0c;每个版本都带来了新特性和改进。然而&#xff0c;这也带来了一些问题&#xff0c;比如不同的工程&#xff0c;需要…

鸿蒙原生开发之状态管理V2

一、ArkTS状态变量的定义&#xff1a; State&#xff1a;状态&#xff0c;指驱动UI更新的数据。用户通过触发组件的事件方法&#xff0c;改变状态数据。状态数据的改变&#xff0c;引起UI的重新渲染。 在鸿蒙原生开发中&#xff0c;使用ArkTS开发UI的时候&#xff0c;我们可以…

nginx配置跳转设置Host有误导致报404问题

我们有个项目&#xff0c;前端调用了第三方接口。为了避免跨域&#xff0c;所以使用nginx进行转发。一直正常工作&#xff0c;相安无事。近日第三方调整了安全策略&#xff0c;http转换成https&#xff0c;原本使用ip&#xff0c;现在也改成使用域名&#xff0c;所以nginx这里我…

深度学习 Deep Learning 第12章 深度学习的主流应用

深度学习 Deep Learning 第12章 深度学习的主流应用 内容概要 本周深入探讨了深度学习在多个领域的应用&#xff0c;包括计算机视觉、语音识别、自然语言处理以及其他领域如推荐系统和知识表示。本章强调了硬件和软件基础设施的重要性&#xff0c;特别是GPU在加速神经网络训练…

【Qt】三种操作sqlite3的方式及其三种多表连接

一、sqlite3与MySQL数据库区别&#xff1a; 1. 数据库类型 SQLite3&#xff1a;是嵌入式数据库&#xff0c;它将整个数据库存储在单个文件中&#xff0c;不需要独立的服务器进程。这意味着它可以很方便地集成到各种应用程序中&#xff0c;如移动应用、桌面应用等。MySQL&…

mysqlworkbench导入.sql文件

1、MySQL Workbench 新建数据库 或者 在左侧导航栏的 ​Schemas 区域右键选择 ​Create Schema...输入数据库名称&#xff08;例如 mydatabase&#xff09;&#xff0c;点击 ​Apply确认创建&#xff0c;点击 ​Finish 2、选择目标数据库 在左侧导航栏的 ​Schemas 列表中&a…

《Spring Cloud Eureka 高可用集群实战:从零构建高可靠性的微服务注册中心》

从零构建高可用 Eureka 集群 | Spring Cloud 微服务架构深度实践指南 本文核心内容基于《Spring Cloud 微服务架构开发》第1版整理&#xff0c;结合生产级实践经验优化 实验环境&#xff1a;IntelliJ IDEA 2024 | JDK 1.8| Spring Boot 2.1.7.RELEASE | Spring Cloud Greenwich…

实变函数:集合与子集合一例(20250329)

题目 设 r , s , t r, s, t r,s,t 是三个互不相同的数&#xff0c;且 A { r , s , t } A \{r, s, t\} A{r,s,t}, B { r 2 , s 2 , t 2 } B \{r^2, s^2, t^2\} B{r2,s2,t2}, C { r s , s t , r t } C \{rs, st, rt\} C{rs,st,rt} 若 A B C A B C ABC 则 { r , s…

Redis设计与实现-哨兵

哨兵模式 1、启动并初始化sentinel1.1 初始化服务器1.2 使用Sentinel代码1.3 初始化sentinel状态1.4 初始化sentinel状态的master属性1.5 创建连向主服务器的网络连接 2、获取主服务器信息3、获取从服务器的信息4、向主从服务器发送信息5、接受主从服务器的频道信息6、检测主观…

蓝桥杯省模拟赛 字符串拼接

问题描述 给定四个字符串 a,b,c,d&#xff0c;请将这四个字符串按照任意顺序依次连接拼成一个字符串。 请问拼成的字符串字典序最小是多少&#xff1f; 输入格式 输入四行&#xff0c;每行包含一个字符串。 输出格式 输出一行包含一个字符串&#xff0c;表示答案。 样例…

【大前端系列20】JavaScript核心:项目实战从零构建任务管理系统

JavaScript核心&#xff1a;项目实战从零构建任务管理系统 系列: 「全栈进化&#xff1a;大前端开发完全指南」系列第20篇 核心: 将JavaScript异步编程、事件循环等核心知识应用于实际项目开发 &#x1f4cc; 引言 在前面的文章中&#xff0c;我们深入探讨了JavaScript中的异步…

STM32单片机的桌面宠物机器人(基于HAL库)

效果 基于STM32单片机的桌面宠物机器人 概要 语音模块&#xff1a;ASR PRO&#xff0c;通过天问block软件烧录语音指令 主控芯片&#xff1a;STM32F103C8T6 使用HAL库 屏幕&#xff1a;0.96寸OLED屏&#xff0c;用来显示表情 4个舵机&#xff0c;用来当作四只腿 底部一个面…

计算机视觉初步(环境搭建)

1.anaconda 建议安装在D盘&#xff0c;官网正常安装即可&#xff0c;一般可以安装windows版本 安装成功后&#xff0c;可以在电脑应用里找到&#xff1a; 2.创建虚拟环境 打开anaconda prompt&#xff0c; 可以用conda env list 查看现有的环境&#xff0c;一般打开默认bas…

SQL Server数据库引擎服务启动失败:端口冲突

问题现象&#xff1a; SQL Server 2022 安装完成后&#xff0c;数据库引擎服务无法启动&#xff0c;日志报错 “TCP 端口 1433 已被占用”&#xff08;ERROR_LOG_SYS_TCP_PORT&#xff09;。 快速诊断 检测端口占用&#xff1a; # 查看 1433 端口占用情况&#xff08;需管理员权…

全局思维与系统思考

最近接到一些需求&#xff0c;1号位希望每个层级的领导者有眼界&#xff0c;胸怀&#xff0c;格局&#xff0c;全局观&#xff0c;这些听起来似乎很抽象&#xff0c;然而它们是每个人、每个团队成长与成功的核心竞争力。那么&#xff0c;如何才能提升这些能力&#xff1f;就像我…

区间有关的贪心解题记录435无重叠区间452用最少数量的箭引爆气球

无重叠区间我的想法是开一个数组a&#xff0c;遍历给出的区间&#xff0c;在数组a里将对应落在的区间index标记。如果有重复区间就只选择最小的那个区间标记。但是这道题的区间好像很长-5 * 104 < starti < endi < 5 * 104没法用数组a表示总的区间范围。 核心思路是当…

天锐蓝盾终端安全防护——企业终端设备安全管控

从办公室的台式电脑到员工手中的移动终端&#xff0c;这些设备不仅是工作的得力助手&#xff0c;更是企业数据的重要载体。然而&#xff0c;随着终端设备的广泛使用&#xff0c;安全风险也如影随形。硬件设备使用不当、数据随意传输等问题频发&#xff0c;使得企业数据面临着泄…

k8s网络策略

k8s网络策略 k8s网络测试概述查看防火墙策略 k8s网络策略网络访问控制案例&#xff1a;配置k8s网络策略结果验证 k8s网络策略配置示例 k8s网络测试概述 网络策略就是设置防火墙 查看防火墙策略 # 获取当前命名空间下的所有 NetworkPolicy 资源&#xff08;网络策略&#xff0…