react-leftlet 实战:一个demo

直接上代码。

import React, {PureComponent} from 'react';
import {useState, useEffect, useRef, useMemo} from 'react';
import { connect } from 'dva';
import { Layout } from 'antd';
import styles from './leafletPage.less';

import L from 'leaflet';
// import {Map, TileLayer, Marker, Popup} from 'react-leaflet';
import {MapContainer, TileLayer, Marker, Popup} from 'react-leaflet';
import 'leaflet/dist/leaflet.css';

// const { Content } = Layout;

//把图标重新引入
// delete L.Icon.Default.prototype._getIconUrl;
// L.Icon.Default.imagePath = '';
// L.Icon.Default.mergeOptions({
//   iconUrl: 'https://leafletjs.com/docs/images/twitter-round.png',
//   shadowUrl: '',
// });

let IconA = L.icon({
  iconUrl: require('../../../assets/markers/marker-icon.png'),
  shadowUrl: ''
});
let IconB = L.icon({
  iconUrl: 'https://leafletjs.com/docs/images/twitter-round.png',
  shadowUrl: '',
  iconSize: [32, 32]
});

//处理每一个marker的显示
const PopupMarker = ({ children, position }) => {
  const items = children.map(item => (
    <span key={item.key} blue'}}>
      {item.string}
      <br />
    </span>
  ));

  const [one, setOne] = useState(null)
  const markerRef = useRef(null)
  const popRef = useRef(null)

  const eventHandlers = useMemo(
    () => ({
      mouseover() {
        console.log(markerRef)
        const marker = markerRef.current        
        marker.openPopup()
      },
      mouseout() {
        const marker = markerRef.current
        marker.closePopup()
      }
    }),
    [],
  )

  // const FuncOnMouseOver = (e) => {
  //   console.log(markerRef)
  //   console.log(popRef)
  //   const marker = markerRef.current
  //   const pop = popRef.current
  //   // marker.openPopup(pop)    

  //   console.log(marker)
  //   console.log(pop)
  //   console.log(marker.isPopupOpen)
  //   console.log(markerRef.isPopupOpen)
  //   console.log(pop.unbindPopup)
  //   console.log(pop.unbindPopup)
  // }

  const m = Math.random()
  console.log(m)
  let icon = m > 0.5 ? IconA : IconB

  return (
    <Marker ref={markerRef} 
    eventHandlers={eventHandlers} 
    // onClick={e => {alert('???')}}
    // onMouseOver={FuncOnMouseOver}
    icon={icon} position={position}>
      <Popup ref={popRef}>
        <div>{items}</div>
      </Popup>
    </Marker>
  );
};
//处理markerlist
const MarkersList = ({ markers }) => {
  const items = markers.map(({ key, ...props }) => <PopupMarker key={key} {...props} />);
  return <div>{items}</div>;
};

//连接models
// @connect(({site,loading}) => ({site,loading:loading.models.site}))

export default class LeafletMarker extends PureComponent {
    //去拿mock的数据
    componentDidMount(){
       const {dispatch} = this.props;
      //  dispatch({
      //      type:'site/fetch',
      //  });
    }
    
    render() {
        // const { site: { data }, loading } = this.props;
        //console.log({ data });
        const position = [22.7047, 113.302]; //中心点

        // const dataList = { data }.data.list;
        const dataList = (() => {
          let arr = []
          for (let i = 0; i < 9; i++) {
            arr.push({
              Id: i,
              Name: `site ${i}`,
              Lat: 22.7047 + `${i}` / 1000,
              Lng: 113.302 - `${i}` / 1000,
              currentValue: Math.floor(Math.random() * 1000),
              status: Math.floor(Math.random() * 10) % 2,
              purchaseDate: new Date(`2017-07-${Math.floor(i / 2) + 1}`),
              create_time: new Date(`2017-07-${Math.floor(i / 2) + 1}`),
              progress: Math.ceil(Math.random() * 100),
              Province: Math.floor(Math.random() * 10) % 2 ? '省份1' : '省份2',
              City: Math.floor(Math.random() * 10) % 2 ? '城市1' : '城市2',
              Maintainer: `m${i}`,
            })
          }
          return arr
        })()

        let cellPoints = [];

        dataList.map(item => {
        let lng = Number.parseFloat(item.Lng);
        let lat = Number.parseFloat(item.Lat);
        let name = item.Name;
        let city = item.City || '';
        let district = item.District || '';
        let address = item.Address || '';
        let maintainer = item.Maintainer || '';
        let popupContent = [{key:city,string:`城市:${city}`},
        {key:name,string:`基站名称:${name}`},
        {key:lng,string:`经度:${lng}`},
        {key:lat,string:`纬度:${lat}`},
        {key:district,string:`地区:${district}`},
        {key:address,string:`地址:${address}`},
        {key:maintainer,string:`维护人员:${maintainer}`},
        ]
        cellPoints.push({key:name,position:[lat, lng],children:popupContent}); //重新组合marker数据
        });

        const style = {
            width: '100%',
            height: '600px',
          };
        return (
            // <Content>
            //   <div className="ant-card-bordered" style={style}>
            //     <Map center={position} zoom={13} 100%', height: '100%' }}>
            //       <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
            //       <MarkersList markers={cellPoints} />                 
            //     </Map>
            //   </div>
            // </Content>
            <MapContainer center={position} 
            minZoom={13}
            maxZoom={13}
            zoom={13} 
            doubleClickZoom={false} dragging={false} scrollWheelZoom={false} boxZoom={false} touchZoom={false}
             1000px', height: '700px' }}>
              <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
              <MarkersList markers={cellPoints} />
            </MapContainer>
        );
    }
}

版本很重要,也展示一下。

{
  "private": true,
  "scripts": {
    "start": "umi dev",
    "build": "umi build",
    "test": "umi test",
    "lint": "eslint --ext .js src mock tests",
    "precommit": "lint-staged"
  },
  "dependencies": {
    "echarts": "^4.4.0",
    "leaflet": "^1.7.1",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-leaflet": "^3.0.0",
    "reqwest": "^2.0.5",
    "umi-request": "^1.2.8",
    "wangeditor": "^4.2.2"
  },
  "devDependencies": {
    "babel-eslint": "^9.0.0",
    "eslint": "^5.4.0",
    "eslint-config-umi": "^1.4.0",
    "eslint-plugin-flowtype": "^2.50.0",
    "eslint-plugin-import": "^2.14.0",
    "eslint-plugin-jsx-a11y": "^5.1.1",
    "eslint-plugin-react": "^7.11.1",
    "husky": "^0.14.3",
    "lint-staged": "^7.2.2",
    "react-test-renderer": "^16.7.0",
    "umi": "^2.7.7",
    "umi-plugin-react": "^1.8.4"
  },
  "lint-staged": {
    "*.{js,jsx}": [
      "eslint --fix",
      "git add"
    ]
  },
  "engines": {
    "node": ">=8.0.0"
  }
}

以上。