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.pswp.cn/diannao/76068.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/76068.shtml
英文地址,請注明出處:http://en.pswp.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…