VueJs 引入百度地图报错: BMap is undefined

本文介绍如何在Vue项目中采用动态加载方式引入百度地图API,解决因异步加载导致的BMap未定义问题,并提供了一个实用的解决方案。
Vue 项目中引入百度地图,想采用动态加载的方式,因为无需在每个页面统一引入。

考虑到加载问题,将动态加载代码放入到 created() 生命周期方法中:
        let scriptNode = document.createElement('script');
        scriptNode.src = '//api.map.baidu.com/api?v=2.0&ak=' + AK + '&callback=bMapInit';
        document.body.appendChild(scriptNode);
	
发现报错:
	BMap is undefined

因为异步加载,导致 BMap 使用时,未定义。

网上找了找,基本都是同一篇解决方案(可能其他的我没看到):
	https://segmentfault.com/a/1190000012815739

按照上述方法生效!这里再书写一遍:

定义一个 utils/bmap.js 文件
	
	// 这个导入百度地图 AK 配置,项目里将所有的配置信息都放在 configs/app.js
	import {APP_CONFIG} from '../configs/app.js';
	export default {
	    init: function (){
	        return new Promise((resolve, reject) => {
	            // 如果已加载直接返回
	            if(typeof BMap !== "undefined") {
	                resolve(BMap);
	                return true;
	            }
	            // 百度地图异步加载回调处理
	            window.bMapInit = function () {
	                // console.log("百度地图脚本初始化成功...");
	                resolve(BMap);
	            };

	            // 插入script脚本
	            let scriptNode = document.createElement('script');
	            scriptNode.src = '//api.map.baidu.com/api?v=2.0&ak=' + APP_CONFIG.BAIDU_MAP_APP_AK + '&callback=bMapInit';
	            document.body.appendChild(scriptNode);
	        });
	    },
	};

vue 使用:
    import BMap from './utils/bmap.js';

    BMap.init()
    .then(BMap => {
        var map = new BMap.Map("lbs-map", {
            enableMapClick: false,              // 禁用底图点击功能
        });
    });

在 Vue 中使用百度地图,不止这一个坑,其他的根据自己项目中碰到的问题,来调试着解决。

 

<think>好的,用户想在Vue3中使用百度地图API实现动态运动轨迹效果。首先,我需要回忆一下相关的步骤和可能的注意事项。根据引用[3],提到了两种方式,其中一种是便捷方式,可能涉及直接使用百度地图的API方法。另外,引用[2]和[3]都提到了Vue3和百度地图的结合,所以需要整合这些信息。 首先,用户需要注册百度地图开发者账号并获取AK密钥,这一步是基础,必不可少。然后,在Vue3项目中引入百度地图的JavaScript API,通常是在index.html中添加script标签,但可能也需要使用动态加载的方法,比如在组件中按需加载,避免全局污染。 接下来,在Vue3组件中初始化地图。这里可能需要使用onMounted生命周期钩子,确保DOM加载完毕后再初始化地图。引用[3]可能提到了一些初始化时的配置,比如设置中心点坐标、缩放级别等。 然后是轨迹生成部分。用户需要动态更新坐标点,这里可能需要使用定时器模拟数据,或者从后端接口获取实时数据。根据引用[3]的两种方式,一种是使用BMap.Polyline直接绘制折线,另一种可能更复杂,比如使用路书或其他高级功能。不过用户的问题主要是动态轨迹,所以使用Polyline应该是比较直接的方法。 动态更新轨迹的话,可能需要维护一个坐标数组,每次添加新坐标后,重新绘制折线。但直接清除旧的折线再添加新的可能效率不高,引用[3]的第二种方式可能涉及更高效的更新方式,比如更新坐标数组并重绘。或者使用百度地图的覆盖物管理方法,比如先移除旧的Polyline再添加新的。 另外,考虑性能优化,比如防抖处理、适当调整更新频率,避免页面卡顿。引用[2]中提到了使用flv.js处理视频流,可能对实时性有要求,但轨迹部分需要注意内存泄漏,及时清理不再需要的覆盖物。 还有,自定义样式,比如轨迹颜色、粗细,这些可以通过Polyline的配置选项来实现。可能还需要添加标记点,比如起点和终点,使用BMap.Marker类。 测试的时候,可能需要模拟坐标数据,使用setInterval来定时生成新的点,并调用更新轨迹的方法。同时,处理组件卸载时的清理工作,比如清除定时器和地图实例,防止内存泄漏。 最后,根据引用[2]和[3],可能需要处理一些常见问题,比如地图加载不完整、坐标偏移、性能问题。例如,使用v-if控制地图容器的渲染,确保DOM准备就绪;使用GPS坐标转换工具类处理坐标偏差;以及使用requestAnimationFrame优化动画流畅度。 总结步骤应该是:注册AK、引入API、初始化地图、生成轨迹线、动态更新坐标、优化性能。同时,注意Vue3的组合式API写法,使用ref或reactive管理响应式数据,生命周期钩子处理初始化和清理。</think>### 步骤详解:Vue3 中集成百度地图实现动态运动轨迹 #### 1. 注册百度地图开发者账号并获取 AK - 访问[百度地图开放平台](https://lbsyun.baidu.com/)创建应用,获取服务端或浏览器端 AK 密钥[^3]。 #### 2. 在 Vue3 项目中引入百度地图 API ```html <!-- index.html --> <script type="text/javascript" src="https://api.map.baidu.com/api?v=3.0&ak=你的AK"></script> ``` #### 3. 初始化地图组件 ```vue <!-- MapComponent.vue --> <template> <div ref="mapContainer" class="map-container"></div> </template> <script setup> import { ref, onMounted } from 'vue'; const mapContainer = ref(null); let map = null; onMounted(() => { // 初始化地图实例 map = new BMap.Map(mapContainer.value, { minZoom: 5, maxZoom: 19 }); // 设置中心点和缩放级别 map.centerAndZoom(new BMap.Point(116.404, 39.915), 13); // 启用缩放控件 map.addControl(new BMap.NavigationControl()); }); </script> <style> .map-container { width: 100%; height: 600px; } </style> ``` #### 4. 生成动态运动轨迹 ```vue <script setup> import { onMounted, onBeforeUnmount } from 'vue'; // 轨迹坐标点数组(示例数据) const path = ref([ new BMap.Point(116.404, 39.925), new BMap.Point(116.414, 39.935), new BMap.Point(116.424, 39.945) ]); let polyline = null; // 轨迹线实例 let timer = null; // 定时器 // 绘制初始轨迹 const drawPath = () => { polyline = new BMap.Polyline(path.value, { strokeColor: "#00a2ff", strokeWeight: 4, strokeOpacity: 0.8 }); map.addOverlay(polyline); }; // 动态更新轨迹 const updatePath = () => { timer = setInterval(() => { // 模拟新增坐标点(实际从接口获取) const newPoint = new BMap.Point( 116.424 + Math.random() * 0.01, 39.945 + Math.random() * 0.01 ); path.value.push(newPoint); // 清除旧轨迹并重新绘制 map.removeOverlay(polyline); drawPath(); }, 2000); }; onMounted(() => { drawPath(); updatePath(); }); // 组件卸载前清理 onBeforeUnmount(() => { clearInterval(timer); map.removeOverlay(polyline); }); </script> ``` #### 5. 添加轨迹标记点 ```javascript // 添加起点终点标记 const addMarkers = () => { const startIcon = new BMap.Icon('start.png', new BMap.Size(32, 32)); const endIcon = new BMap.Icon('end.png', new BMap.Size(32, 32)); const startMarker = new BMap.Marker(path.value[0], { icon: startIcon }); const endMarker = new BMap.Marker(path.value[path.value.length-1], { icon: endIcon }); map.addOverlay(startMarker); map.addOverlay(endMarker); }; ``` #### 6. 性能优化建议 - **坐标更新策略** 使用双缓冲机制:维护两个坐标数组交替更新,减少地图覆盖物频繁增删操作[^3]。 ```javascript let activePath = [...path.value]; let bufferPath = []; // 更新时切换缓冲区 const switchBuffer = () => { bufferPath.push(newPoint); if (bufferPath.length >= 50) { activePath = bufferPath; bufferPath = []; redrawPath(activePath); } }; ``` - **动画流畅性** 采用`requestAnimationFrame`替代`setInterval`: ```javascript const animate = () => { updatePath(); requestAnimationFrame(animate); }; ``` #### 常见问题解决 1. **地图容器未渲染** 使用`v-if`控制地图容器的渲染时机: ```vue <div v-if="mapLoaded" ref="mapContainer"></div> ``` 数据加载完成后再设置`mapLoaded = true`。 2. **坐标偏移问题** 使用百度地图提供的坐标转换工具类: ```javascript const convertor = new BMap.Convertor(); convertor.translate([gpsPoint], 1, 5, (res) => { if (res.status === 0) { const bdPoint = res.points[0]; } }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值