@uiw/react-amap-map
Version:
基于 React 封装的高德地图组件。AMap Component Based On React.
378 lines (321 loc) • 17.9 kB
Markdown
<div markdown="1">
<sup>使用 <a href="https://wangchujiang.com/#/app" target="_blank">我的应用</a> 也是一种 <a href="https://wangchujiang.com/#/sponsor" target="_blank">支持</a> 我的方式:</sup>
<br>
<a target="_blank" href="https://apps.apple.com/app/Vidwall/6747587746" title="Vidwall for macOS"><img align="center" alt="Vidwall" height="52" width="52" src="https://github.com/user-attachments/assets/7b5df70a-ed91-4d4b-85be-f00e60a09ce9"></a>
<a target="_blank" href="https://wangchujiang.com/mousio-hint/" title="Mousio Hint for macOS"><img align="center" alt="Mousio Hint" height="52" width="52" src="https://github.com/user-attachments/assets/3c0af128-0cef-44e5-a8db-4741dc5a6690"></a>
<a target="_blank" href="https://apps.apple.com/app/6746747327" title="Mousio for macOS"><img align="center" alt="Mousio" height="52" width="52" src="https://github.com/user-attachments/assets/9edf61ff-5a6c-4676-9cc2-8fd3c1ad0dfb"></a>
<a target="_blank" href="https://apps.apple.com/app/6745227444" title="Musicer for macOS"><img align="center" alt="Musicer" height="52" width="52" src="https://github.com/user-attachments/assets/b7abfba8-88ff-4c86-a125-43073d5aef22"></a>
<a target="_blank" href="https://apps.apple.com/app/6743841447" title="Audioer for macOS"><img align="center" alt="Audioer" height="52" width="52" src="https://github.com/user-attachments/assets/7a836865-8c90-4119-87bc-19e06a76c957"></a>
<a target="_blank" href="https://apps.apple.com/app/6744690194" title="FileSentinel for macOS"><img align="center" alt="FileSentinel" height="52" width="52" src="https://github.com/user-attachments/assets/28bce2cc-290e-45bf-9068-585ff6ecafe9"></a>
<a target="_blank" href="https://apps.apple.com/app/6743495172" title="FocusCursor for macOS"><img align="center" alt="FocusCursor" height="52" width="52" src="https://github.com/user-attachments/assets/d543668a-737b-4853-a6bb-eaa269e69836"></a>
<a target="_blank" href="https://apps.apple.com/app/6742680573" title="Videoer for macOS"><img align="center" alt="Videoer" height="52" width="52" src="https://github.com/user-attachments/assets/10ffb0f1-0625-40d6-93f1-2c2496592595"></a>
<a target="_blank" href="https://apps.apple.com/app/6740425504" title="KeyClicker for macOS"><img align="center" alt="KeyClicker" height="52" width="52" src="https://github.com/user-attachments/assets/5a19fcb9-cb81-4855-b4ea-31c604d9612a"></a>
<a target="_blank" href="https://apps.apple.com/app/6739052447" title="DayBar for macOS"><img align="center" alt="DayBar" height="52" width="52" src="https://github.com/user-attachments/assets/771b608d-594c-492d-8532-d9231e383f5b"></a>
<a target="_blank" href="https://apps.apple.com/app/6739444407" title="Iconed for macOS"><img align="center" alt="Iconed" height="52" width="52" src="https://github.com/user-attachments/assets/8a35dc7b-4faf-4e2a-9311-f66d6844a896"></a>
<a target="_blank" href="https://apps.apple.com/app/6737160756" title="RightMenu Master for macOS"><img align="center" alt="RightMenu Master" height="52" width="52" src="https://github.com/user-attachments/assets/39a76541-71bf-4de7-a01c-c62f0557dff5"></a>
<a target="_blank" href="https://apps.apple.com/app/6723903021" title="Paste Quick for macOS"><img align="center" alt="Quick RSS" height="52" width="52" src="https://github.com/user-attachments/assets/bdaad5b7-9810-44ce-8f17-8410864465d2"></a>
<a target="_blank" href="https://apps.apple.com/app/6670696072" title="Quick RSS for macOS/iOS"><img align="center" alt="Quick RSS" height="52" width="52" src="https://github.com/user-attachments/assets/374106b5-a448-4d1d-9ccb-b04b6bc681ed"></a>
<a target="_blank" href="https://apps.apple.com/app/6670167443" title="Web Serve for macOS"><img align="center" alt="Web Serve" height="52" width="52" src="https://github.com/user-attachments/assets/e1d9f76f-0f3d-4ba5-8a15-253ee173bb1c"></a>
<a target="_blank" href="https://apps.apple.com/app/6503953628" title="Copybook Generator for macOS/iOS"><img align="center" alt="Copybook Generator" height="52" width="52" src="https://github.com/jaywcjlove/jaywcjlove/assets/1680273/b90e42ff-158b-4534-82ca-5898fd0e8d73"></a>
<a target="_blank" href="https://apps.apple.com/app/6471227008" title="DevTutor for macOS/iOS"><img align="center" alt="DevTutor for SwiftUI" height="52" width="52" src="https://github.com/jaywcjlove/jaywcjlove/assets/1680273/f15c154d-0192-48eb-8e0e-9e245ffd974a"></a>
<a target="_blank" href="https://apps.apple.com/app/6479819388" title="RegexMate for macOS/iOS"><img align="center" alt="RegexMate" height="52" width="52" src="https://github.com/jaywcjlove/jaywcjlove/assets/1680273/aabe5aa9-9a96-4390-8bed-c3e4023d0dea"></a>
<a target="_blank" href="https://apps.apple.com/app/6479194014" title="Time Passage for macOS/iOS"><img align="center" alt="Time Passage" height="52" width="52" src="https://github.com/jaywcjlove/time-passage/assets/1680273/6f30e429-e6f3-4dbe-9921-a5effe2a05e9"></a>
<a target="_blank" href="https://apps.apple.com/app/6478772538" title="IconizeFolder for macOS"><img align="center" alt="Iconize Folder" height="52" width="52" src="https://github.com/jaywcjlove/jaywcjlove/assets/1680273/fa9d8b9c-1e51-4ded-877c-fa5b21c47220"></a>
<a target="_blank" href="https://apps.apple.com/app/6478511402" title="Textsound Saver for macOS/iOS"><img align="center" alt="Textsound Saver" height="52" width="52" src="https://github.com/jaywcjlove/jaywcjlove/assets/1680273/0595e842-980b-4574-8891-a8ba853a08be"></a>
<a target="_blank" href="https://apps.apple.com/app/6476924627" title="Create Custom Symbols for macOS"><img align="center" alt="Create Custom Symbols" height="52" width="52" src="https://github.com/jaywcjlove/jaywcjlove/assets/1680273/8cd022ce-a3f1-4e89-b7c6-6fbd0d4db77c"></a>
<a target="_blank" href="https://apps.apple.com/app/6476452351" title="DevHub for macOS"><img align="center" alt="DevHub" height="52" width="52" src="https://github.com/user-attachments/assets/4a44a4fd-67ce-430b-af0a-72f18feaa47d"></a>
<a target="_blank" href="https://apps.apple.com/app/6476400184" title="Resume Revise for macOS"><img align="center" alt="Resume Revise" height="52" width="52" src="https://github.com/jaywcjlove/jaywcjlove/assets/1680273/c9954a20-1905-48de-bdf8-d71837974aa2"></a>
<a target="_blank" href="https://apps.apple.com/app/6472593276" title="Palette Genius for macOS"><img align="center" alt="Palette Genius" height="52" width="52" src="https://github.com/jaywcjlove/jaywcjlove/assets/1680273/27340413-d355-45b2-8f6f-6ac37682d957"></a>
<a target="_blank" href="https://apps.apple.com/app/6470879005" title="Symbol Scribe for macOS"><img align="center" alt="Symbol Scribe" height="52" width="52" src="https://github.com/jaywcjlove/jaywcjlove/assets/1680273/c7249f05-fa70-4def-a1e9-571d5f171fc9"></a>
</div>
<hr>
Map 组件
===
[](https://jaywcjlove.github.io/#/sponsor)
[](https://www.npmjs.com/package/@uiw/react-amap-map)
[](https://www.npmjs.com/package/@uiw/react-amap-map)
Map 组件是其他组件的基础,Map 组件会通过 Context 给所有的子组件提供 **`map`**,**`container`** 和 **`AMap`**,对象。
⚠️ 注意
> 1. 组件 `<Map>` 必须包裹在 `<APILoader>` 组件内,该组件作用是加载高德地图 SDK。
> 2. 其他地图组件必须作为 `<Map>` 的子组件使用;
> 3. 在 ~~v2.5.0+~~ -> v5 通过 props 传递 **`map`**,**`container`** 和 **`AMap`** 对象,在 v6 版本中移除了,通过 Context 传递对象
```jsx
import { Map, APILoader } from '@uiw/react-amap';
// 或者单独安装使用
import { Map } from '@uiw/react-amap-map';
```
### 基本用法
Map 的父组件必须具有宽度和高度;
```jsx mdx:preview
import React from 'react';
import ReactDOM from 'react-dom';
import { Map, APILoader } from '@uiw/react-amap';
const Demo = () => (
<div style={{ width: '100%', height: '300px' }}>
<APILoader akey="a7a90e05a37d3f6bf76d4a9032fc9129">
<Map />
</APILoader>
</div>
);
export default Demo
```
### useMapContext
通过 React 的 Context 提供了一个`无需`为每层组件手动注入 ~~`map`~~,~~`container`~~ 和 ~~`AMap`~~ 三个属性 `props`,就能在组件树间进行传递。
```jsx mdx:preview
import React, { useRef, useEffect } from 'react';
import ReactDOM from 'react-dom';
import { useMap, useMapContext, APILoader, Provider } from '@uiw/react-amap';
const Marker = () => {
const warpper = useRef(null);
const { map, state } = useMapContext();
const { setContainer } = useMap({
container: warpper.current,
center: [116.397428, 39.90923],
zoom: 10
});
useEffect(() => {
if (map) {
const marker = new AMap.Marker({
icon: new AMap.Icon({
imageSize: new AMap.Size(25, 34),
image: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png'
}),
position: [116.405285,39.904989],
offset: new AMap.Pixel(-13, -30)
});
// 创建点标记
const marker1 = new AMap.Marker({
position: new AMap.LngLat(116.32945,39.939772)
});
map.add(marker1);
marker.setMap(state.map);
}
}, [map]);
useEffect(() => {
if (warpper.current) {
setContainer(warpper.current);
}
}, [warpper.current]);
return <div ref={warpper} style={{ height: 300 }} />;
}
const Demo = () => (
<APILoader akey="a7a90e05a37d3f6bf76d4a9032fc9129">
<Provider>
<Marker />
</Provider>
</APILoader>
);
export default Demo
```
```jsx
import { useMapContext, Provider } from '@uiw/react-amap';
const { AMaps, map, container, state, dispatch } = useMapContext();
// => state.AMaps
// => state.map
// => state.container
```
### 参数设置
```jsx mdx:preview
import ReactDOM from 'react-dom';
import React, { Fragment, useState } from 'react';
import { Map, APILoader } from '@uiw/react-amap';
function Demo() {
const [dragEnable, setDragEnable] = useState(true);
const [display, setDisplay] = useState(true);
const [zoom, setZoom] = useState(15);
const [center, setCenter] = useState([116.397428, 39.90923]);
const [viewMode, setViewMode] = useState('3D');
return (
<Fragment>
<button onClick={() => setDragEnable(!dragEnable)}>{dragEnable ? '禁用' : '启用'}拖拽</button>
<button onClick={() => setDisplay(!display)}>{display ? '卸载' : '加载'}地图</button>
<button onClick={() => setViewMode(viewMode === '3D' ? '2D' : '3D')}>{viewMode}地图</button>
<button onClick={() => setZoom(zoom + 1)}>放大 +1 -> ({zoom})</button>
<button onClick={() => setZoom(zoom - 1)}>缩小 -1 -> ({zoom})</button>
<button onClick={() => setZoom(zoom - 1)}>缩小 -1 -> ({zoom})</button>
<button onClick={() => setCenter([121.394147,31.262488])}>上海</button>
<button onClick={() => setCenter([116.397428, 39.90923])}>北京</button>
<div style={{ width: '100%', height: 350 }}>
{display && (
<Map
dragEnable={dragEnable}
zoom={zoom}
center={center}
viewMode={viewMode}
pitch={viewMode === '2D' ? 0 : 70}
/>
)}
</div>
</Fragment>
);
}
const Mount = () => (
<APILoader akey="a7a90e05a37d3f6bf76d4a9032fc9129">
<Demo />
</APILoader>
);
export default Mount;
```
### Ref
获取地图实例对象。
```jsx mdx:preview
import ReactDOM from 'react-dom';
import React, { useEffect, useRef, Fragment } from 'react';
import { Map, APILoader } from '@uiw/react-amap';
function Demo() {
const mapRef = useRef();
useEffect(() => {
console.log('mapRef:', mapRef)
}, []);
return (
<div style={{ width: '100%', height: 130 }}>
<Map
layers={[new AMap.TileLayer.Satellite()]}
ref={(instance) => {
if (instance && instance.map) {
const bounds = instance.map.getBounds();
console.log('instance', instance);
}
}}
/>
<Map
layers={[new AMap.TileLayer.Satellite()]}
ref={mapRef}
/>
</div>
);
}
const Mount = () => (
<div style={{ width: '100%', height: '300px' }}>
<APILoader akey="a7a90e05a37d3f6bf76d4a9032fc9129">
<Demo />
</APILoader>
</div>
);
export default Mount;
```
### 事件触发
```jsx mdx:preview
import ReactDOM from 'react-dom';
import React from 'react';
import { Map, APILoader } from '@uiw/react-amap';
const Demo = () => (
<div style={{ width: '100%', height: '300px' }}>
<APILoader akey="a7a90e05a37d3f6bf76d4a9032fc9129">
<Map
onComplete={(data, de) => {
console.log('地图加载完成!', data, de);
}}
onClick={() => {
console.log('点击事件!');
}}
/>
</APILoader>
</div>
);
export default Demo
```
### 特殊使用方法
通过 `Map` 的子组件函数,返回三个对象 **`map`**,**`container`** 和 **`AMap`**,
```jsx mdx:preview
import ReactDOM from 'react-dom';
import React, { useEffect, useRef, Fragment } from 'react';
import { Map, APILoader, ScaleControl, ToolBarControl, ControlBarControl, Geolocation } from '@uiw/react-amap';
const Demo = () => (
<div style={{ width: '100%', height: '300px' }}>
<Map center={[116.397428, 39.90923]} zoom={12}>
{({ AMap, map, container }) => {
console.log('map', map)
if (map) {
const marker = new AMap.Marker({
icon: new AMap.Icon({
imageSize: new AMap.Size(25, 34),
image: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png'
}),
position: [116.405285,39.904989],
offset: new AMap.Pixel(-13, -30)
});
marker.setMap(map);
}
return;
}}
</Map>
</div>
);
const Mount = () => (
<APILoader akey="a7a90e05a37d3f6bf76d4a9032fc9129">
<Demo />
</APILoader>
);
export default Mount;
```
### 将子组件封装到一个组件中
```jsx mdx:preview
import ReactDOM from 'react-dom';
import React, { useState, useRef } from 'react';
import { Map, APILoader, Polyline, ToolBarControl } from '@uiw/react-amap';
const path1 = [ [121.099109,31.222311], [118.528308,31.989555], [117.319812,31.803006], [114.353503,30.67583], [115.891589,28.979429], [112.947253,28.188361], ];
const path2 = [ [116.405289, 39.904987], [113.964458, 40.54664], [111.47836, 41.135964], [108.949297, 41.670904], [106.380111, 42.149509], [103.774185, 42.56996], [101.135432, 42.930601], [98.46826, 43.229964], [95.777529, 43.466798], [93.068486, 43.64009], [90.34669, 43.749086], [87.61792, 43.793308], ];
const ChildComp = (props = {}) => {
return (
<div>
<Polyline {...props} visiable={true} strokeOpacity={1} path={path1} />
<Polyline {...props} visiable={true} strokeOpacity={1} path={path2} />
</div>
)
}
const Demo = () => {
const [show, setShow] = useState(true);
return (
<div style={{ width: '100%', height: '300px' }}>
<Map zoom={3}>
{(props) => {
return <ChildComp {...props} />;
}}
</Map>
</div>
);
}
const Mount = () => (
<APILoader akey="a7a90e05a37d3f6bf76d4a9032fc9129">
<Demo />
</APILoader>
);
export default Mount;
```
### Props
[更多参数设置](https://github.com/uiwjs/react-amap/blob/268303d/src/types/core.d.ts#L461-L537)
| 参数 | 说明 | 类型 | 默认值 |
|--------- |-------- |--------- |-------- |
| container | (**默认不需要传递**) 构造一个地图对象,参数 container 中传入地图容器 DIV 对象。<br />注意:地图容器在创建之前必须拥有实际大小,否则可能出现底图无法渲染的问题。 | `HTMLDivElement` | - |
| center | 初始中心经纬度 | `[number, number] \| LngLat` | - |
### 事件
[事件类型文档](https://github.com/uiwjs/react-amap/blob/268303d/src/types/core.d.ts#L298-L403)
| 参数 | 说明 | 类型 |
| ---- | ---- | ---- |
| onComplete | 地图资源加载完成后触发事件 | - |
| onMouseMove | 鼠标在地图上移动时触发 | - |
| onZoomChange | 地图缩放级别更改后触发 | - |
| onMapMove | 地图平移时触发事件 | - |
| onMouseWheel | 鼠标滚轮开始缩放地图时触发 | - |
| onZoomStart | 缩放开始时触发 | - |
| onMouseOver | 鼠标移入地图容器内时触发 | - |
| onMouseOut | 鼠标移出地图容器时触发 | - |
| onDblClick | 鼠标左键双击事件 | - |
| onClick | 鼠标左键单击事件 | - |
| onZoomEnd | 缩放结束时触发 | - |
| onMoveEnd | 地图移动结束后触发,包括平移,以及中心点变化的缩放。如地图有拖拽缓动效果,则在缓动结束后触发 | - |
| onMouseUp | 鼠标在地图上单击抬起时触发 | - |
| onMouseDown | 鼠标在地图上单击按下时触发 | - |
| onRightClick | 鼠标右键单击事件 | - |
| onMoveStart | 地图平移开始时触发 | - |
| onDragStart | 开始拖拽地图时触发 | - |
| onDragging | 拖拽地图过程中触发 | - |
| onDragEnd | 停止拖拽地图时触发。如地图有拖拽缓动效果,则在拽停止,缓动开始前触发 | - |
| onHotspotOut | 鼠标移出热点时触发 | - |
| onHotspotOver | 鼠标滑过热点时触发 | - |
| onTouchStart | 触摸开始时触发事件,仅适用移动设备 | - |
| onHotspotClick | 鼠标点击热点时触发 | - |
| onTouchMove | 拖拽地图过程中触发,仅适用移动设备 | - |
| onTouchEnd | 触摸结束时触发事件,仅适用移动设备 | - |
| onResize | 地图容器尺寸改变事件 | - |