1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > react项目使用百度地图API

react项目使用百度地图API

时间:2023-08-25 22:24:02

相关推荐

react项目使用百度地图API

文章目录

前言一、接入API1、登录百度地图2、创建应用,获取密钥3、引入API4、当作模块导入BMap二、使用1、引入2、展示地图三、效果展示总结

前言

最近在开发一款react项目,其中有一个小功能是地理位置关键词输入提示。多番考虑下,选择接入百度地图API。在使用的过程中,遇到了一些问题,在此记录并分享一下。


一、接入API

首先,我们需要获得百度地图API的使用权,然后才能在项目中引用。

1、登录百度地图

/

2、创建应用,获取密钥

登录后,点击控制台,选择我的应用,点击创建应用,然后保存密钥。

3、引入API

将百度API的script引入到项目的index.html文件。

<script type="text/javascript" src="http://api./api?v=2.0&ak=你的密钥"></script>

4、当作模块导入BMap

在webpack.config.js的module.exports里添加:

externals:{'BMap':'BMap',}

二、使用

1、引入

在jsx文件中引入BMap:

import BMap from 'BMap'

2、展示地图

由于项目需要实现让用户选择某一商品的地理位置,所以需要根据用户输入的关键词给出位置提示,或者通过用户点击地图选择位置。

这一功能作为 antd 的Form中的一项,限制比较大,但能实现。

(1)设置两个内容块放置输入框和地图

(map组件需要设置长宽)

<div id="l-map"></div><input type="text" id="suggestId" />

如果直接在Form.Item中这样写,则只能显示输入框,map框会被隐藏。所以,使用help属性让<div id="l-map"></div>显示:

<Form.Item label="地址" name="address"help={<div id='l-map' className='map'>点我</div>}><input type="text" id="suggestId" /></Form.Item>

(2)在组件第一次渲染后初始化地图

componentDidMount(){map = new BMap.Map("l-map");map.centerAndZoom("北京",12); // 初始化地图,设置城市和地图级别。map.enableScrollWheelZoom(true);//让地图能随鼠标滚轮缩放}

这时,界面上已经能显示输入框和地图了。

(3)添加自动完成对象

var ac = new BMap.Autocomplete( //建立一个自动完成的对象{"input" : "suggestId","location" : map});

将map与input绑定。这样,当在输入框输入时,输入框下方会显示此输入的位置提示信息列表。

按照官方教程,当点击列表中的一项,输入框会呈现你的选择。然而,事与愿违,百度地图API的赋值与React不兼容。React中的Input是受控组件,不能直接id赋值。所以这里,就需要想替代办法了。

我的想法是拦截输出并获取提示列表,然后展示列表并添加事件响应。

(4)设计输出

首先,将其原来的输出列表隐藏:

.tangram-suggestion{display: none;}

采用一种野蛮的方法:检查元素后发现包裹列表的组件类名为“tangram-suggestion”,直接在样式中设置隐藏。

其次,获取位置提示列表,并显示在输入框下。

这里可以使用antd的AutoComplete组件,并且将options属性设置为组件state。只要更新state.addressOptions,就能更新选项了。(onSelect方法后文实现)

<AutoComplete id="suggestId"options={this.state.addressOptions}onSelect={this.onSelect}/>

拦截位置提示列表,并赋值给state.addressOptions。修改自动完成的对象如下:

new BMap.Autocomplete( //建立一个自动完成的对象{"input" : "suggestId","location" : map,onSearchComplete: function(e) {let searchResult=[];for(let i=0;i<e.Hr.length;i++){let _value=e.Hr[i];let a=_value.province + _value.city + _value.district + _value.street + _value.business;searchResult.push({value:a});}this.setState({addressOptions:searchResult});}},);

然后,实现AutoComplete的onSelect方法。onSelect方法传递的参数为列表中所选择的那一项的内容。清除地图上所有覆盖物,然后让地图中心移动到选择的位置。

(map为全局变量,后文解释)

onSelect = (data) => {map.clearOverlays();map.centerAndZoom(data,18);};

(5)添加地图点击响应

当点击地图上某一位置,输入框会显示该位置,并且地图中心移动到选择的位置。

由于点击地图只能获取经纬度信息,所以需要通过BMap.Geocoder转换为地理位置。

map.addEventListener('click', function(e){var pt = e.point;var geoc = new BMap.Geocoder();var addComp;geoc.getLocation(pt, (rs)=>{addComp = rs.address;this.uploadRef.current.setFieldsValue({address: addComp});map.clearOverlays();map.centerAndZoom(pt,18);map.addOverlay(new BMap.Marker(pt));}); });

对于输入框赋值,本人尝试了无数的方法,最终找到一种:setFieldsValue()赋值。this.uploadRef为Form的ref属性,地址输入框的name为address。转换后的处理函数需绑定到组件。

(6)移除事件监听

将触发函数提取为函数:

map.addEventListener('click', this.mapClick);

mapClick=(e)=> {var pt = e.point;var geoc = new BMap.Geocoder();var addComp;geoc.getLocation(pt, (rs)=>{addComp = rs.address;this.uploadRef.current.setFieldsValue({address: addComp});map.clearOverlays();map.centerAndZoom(pt,18);map.addOverlay(new BMap.Marker(pt));}); }

此时,为了能在其他函数中使用map,需要将map设置为全局变量(考虑变量作用域)。在组件外声明:

let map;

在componentWillUnmount移除事件。

componentWillUnmount(){// 注销监听事件map.removeEventListener('click', this.mapClick);}

(7)优化——函数防抖

输入框输入后触发自动完成对象,是一个高频函数。为了减轻资源加载的负担,将函数延迟处理,使用debounce()。

import debounce from 'lodash/debounce';

new BMap.Autocomplete( //建立一个自动完成的对象{"input" : "suggestId","location" : map,onSearchComplete: this.searchComplete},);

searchComplete=(e)=> {// console.log(e);let searchResult=[];for(let i=0;i<e.Hr.length;i++){let _value=e.Hr[i];let a=_value.province + _value.city + _value.district + _value.street + _value.business;searchResult.push({value:a});}this.setState({addressOptions:searchResult});}

this.searchComplete = debounce(this.searchComplete, 500);

三、效果展示

React项目使用百度地图API效果展示.mp4


总结

接入百度地图API这一过程完全是参考前辈们的经验,并没有遇到问题。感谢愿意分享的好心人!

在使用过程中,遇到了形形色色的bug:变量作用域的问题、组件自带函数传递参数的问题、赋值的问题。我通常的处理方式是控制台输出,哪里不清楚就输出哪些。

经过不断的探索,最终找到了一种方式实现了地理位置关键词输入提示这一功能。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。