如何优雅的在React项目中使用高德地图

avatar
前端工程师

Ra822003727c112b0aec94fb30e7a7554.jpeg

目前的使用

1、裸游

(1) 引入高德 JS API

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=您申请的key值">
    </script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

(2)、开发业务逻辑

export default () => {
  const map = useRef<any>();
  const container = useRef<HTMLDivElement>();
  
  useEffect(() => {
    if (container.current) {
      map.current = new AMap.Map(container.current, {
        resizeEnable: true,
        zoom: 16
     })
    }
  }, [container]);
  
  return <div ref={container} />
}

缺点

  • 需要在index.html手动引入高德JS API
  • 存在大量冗余代码,无法跨项目使用

2、使用 饿了么 react-amap

(1)、安装

npm install --save react-amap

(2)、使用

import React from 'react';
import ReactDOM from 'react-dom';
import { Map } from 'react-amap';
 
ReactDOM.render(
  <Map amapkey={YOUR_AMAP_KEY} version={VERSION} />,
  document.querySelector('#app')
)

缺点

  • 没有完整的类型定义,使用必须对照文档去开发
  • 维护不积极,最新发布得版本也是两年前的
  • 组件不够丰富,只包含了部分常用的组件

优雅的使用

作为重度TypeScript使用者,类型定义不全绝对不能忍的,所以新造了个轮子 @pansy/react-amap

文档地址 react-amap-pansyjs.vercel.app

Apr-15-2021 17-45-39.gif

安装

npm install --save @pansy/react-amap

使用

import React from 'react';
import ReactDOM from 'react-dom';
import { Map } from 'react-amap';
 
ReactDOM.render(
  <Map mapKey={YOUR_AMAP_KEY} version={VERSION} />,
  document.querySelector('#app')
)

列举一个具体的列子,介绍 @pans/react-amap 的使用。

需求如下:

用户需要在地图上点击,获取坐标点。

实现思路如下:

  1. 监听地图的click事件,获取经纬度坐标;
  2. 使用Marker组件,渲染标记点;

具体实现代码如下:

import { useState } from 'react';
import { message } from 'antd';
import { Map, Marker } from '@pansy/react-amap';
import type { MapProps } from '@pansy/react-amap/es/map';

export default () => {
  const [position, setPosition] = useState<ReactAMap.Position>();

  const mapEvents: MapProps['events'] = {
    click: (event) => {
      const position: [number, number] = [
        event.lnglat.getLng(), 
        event.lnglat.getLat()
      ];
      message.success(`获取的坐标点位置为${position}`);
      setPosition(position);
    }
  }

  return (
    <div style={{ height: 500 }}>
      <Map events={mapEvents}>
        {position && (
           <Marker position={position} />
        )}
      </Map>
    </div>
  );
};

效果图如下:

Apr-15-2021 18-10-58.gif

目前包含的组件

名称说明
Map地图组件
BezierCurve贝塞尔曲线
BezierCurveEditor编辑贝塞尔曲线,必须作为BezierCurve的子组件使用
Circle圆形
CircleEditor编辑圆形,必须作为Circle的子组件使用
CircleMarker圆点标记
ContextMenu地图右键菜单
ControlBar组合了旋转、倾斜、复位、缩放在内的地图控件, 3D地图使用
Ellipse椭圆
EllipseEditor编辑椭圆,必须作为Ellipse的子组件使用
Heatmap热力图组件
InfoWindow信息窗体
MapType地图类型切换插件,用来切换固定的几个常用图层
Marker单个坐标点
Markers海量坐标点
MouseTool鼠标工具
OverView地图鹰眼
Polygon在地图上显示多边形
Polyline在地图上显示折线
PolyEditor多边形和折线的编辑组件,必须作为其子组件使用
Rectangle在地图上显示矩形
RectangleEditor编辑矩形,必须作为Rectangle的子组件使用
Scale比例尺
ToolBar工具条

如不满足您的需求,欢迎在 issues 讨论。