React引入高德地图(web服务)并完成输入提示

先简单讲解一波,CV师看最后附完整代码

第一步

首先我们需要下载并引入两个插件

npm install --save axios 
npm install --save scriptjs

下载完成后我们新建一个页面并引入以上插件

import axios from 'axios';
import myScript from 'scriptjs'
import { Form, Input } from 'antd';

第二步

定义以下全局变量

const amapKey = '8434182*****************ce12c32b508';//高得地图开放平台申请的key
const gaodeMapSdk = 'https://webapi.amap.com/maps?v=1.4.2&key=' + amapKey;
var map = null;//用于实例化地图
var marker = null;//用于实例化定位图标
var geocoder = null;//用于获取经纬度
var zoomLevel = 15;//默认地图层级(放大缩小)

第三步

在装载前引入地图并且实例化

// 在装载前引入地图CDN
    componentWillMount() {
        if (!window.AMap && !(window.google && window.google.maps)) {
            $script([gaodeMapSdk], function (a, b) { })
        }
    }
    // 在装载后调用我们实例化地图的方法
    componentDidMount() {
        let _this = this;
        _this.listenerStorage();
    }

点击、滑动等事件都可以在这里配置

//实例化地图
listenerStorage = () => {
        let _this = this;
        //判断是否加载地图CDN,否则延时后重新调用
        if (window.AMap || (window.google && window.google.maps)) {
            if (window.AMap) {
                const latlngxy = ["116.397428","39.90923"];//默认地址 北京天安门
                //container为地图容器id,需设置宽高
                map = new window.AMap.Map('container', {
                    resizeEnable: true,
                    center: latlngxy,
                    zoom: zoomLevel
                });
                //高德设置语言    ['en', 'zh_en', 'zh_cn']  
                map.setLang('zh_en');
                // 在新中心点添加定位图标 marker   
                marker = new window.AMap.Marker({
                    map: map,
                    position: latlngxy
                });
                //监听地图点击事件
                map.on('click', function (e) {
                    window.AMap.service('AMap.Geocoder', function () {//回调函数  
                        //实例化Geocoder ,用于获取经纬度
                        geocoder = new window.AMap.Geocoder({});
                        geocoder.getAddress(e.lnglat, function (status, result) {
                            let latlngs = [e.lnglat.lng, e.lnglat.lat]
                            const currentZoom = map.getZoom();
                            //设置地图层级
                            map.setZoomAndCenter(currentZoom != zoomLevel ? currentZoom : zoomLevel, latlngs);		
                            //设置定位图标跟随新坐标
                            marker.setPosition(e.lnglat);
                            //根据经纬度地名
                            axios.get('https://restapi.amap.com/v3/geocode/regeo?location=' + e.lnglat.lng + ',' + e.lnglat.lat + '&key=' + amapKey).then((res) => {
                                //根据地名获取经纬度
                                axios.get('https://restapi.amap.com/v3/geocode/geo?address=' + res.data.regeocode.formatted_address + '&key=' + amapKey).then((ress) => {
                                   //获取地名与经纬度为表单赋值(自行输出查看ress内容选择需要的值最好)
                                    _this.formRef.current.setFieldsValue({
                                    	// ress.data.geocodes[0].location //经纬度(用于传给后端,我就不写了)
                                    	//地名赋值回显到表单
                                        addres: ress.data.geocodes[0].formatted_address
                                    })
                                })
                            })
                        })
                    })
                })
            }
            _this.setState({
                status: 1
            })
        } else {
            setTimeout(function () {
                _this.listenerStorage()
            }, 800)
        }
    }

HTML及CSS代码

formRef = React.createRef();
    constructor(props) {
        super(props)
        this.state = {
            isAmapShow: false,//控制输入提示弹窗显示
            addresList: []//用于接收输入提示列表
        }
    }
render() {
        return (
            <div>
                <Form style={{ width: '500px' }} ref={this.formRef}>
                    <Form.Item label="地址" name="addres" rules={[{ validator: this.phoneValidator }]}>
                        <Input placeholder="请输入地址" autocomplete="off" allowClear />
                    </Form.Item>
                </Form>
                <div id="container" style={{ width: '500px', height: '300px', position: 'relative' }}>
                    {this.state.isAmapShow ? <div style={{ width: '200px', height: '300px', background: '#fff', position: 'absolute', top: '0px', left: '0px' }}>
                        <ul className="addres_list" style={{ padding: '0px', height: '300px', overflowY: 'scroll' }}>
                            {
                                this.state.addresList.map((value, key) => {
                                    return (
                                        <li key={key} style={{
                                            listStyle: 'none', height: '30px', lineHeight: '30px', textIndent: '10px', borderBottom: '1px solid #ccc',
                                            overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap'
                                        }} onClick={this.delFolder.bind(this, value)}>{value.name}</li>
                                    )
                                }
                                )
                            }
                        </ul>
                    </div> : null}
                </div>
            </div>
        )
    }

完成输入提示

//非空判断及关键字搜索
    phoneValidator = (_, value, callback) => {
        if (value) {
            this.setState({
                isAmapShow: true
            })
            axios.get('https://restapi.amap.com/v3/place/text?keywords=' + value + '&offset=20&key=' + amapKey).then((res) => {
                this.setState({
                    addresList: res.data.pois
                })
                return callback();
            })
        } else {
            this.setState({
                isAmapShow: false
            })
            return Promise.reject(new Error('请输入地址'));
        }

    }
    // 选择列表地址
    delFolder = (value, e) => {
        this.setState({
            isAmapShow: false
        })
        let lnglat = value.location.split(',')
        const currentZoom = map.getZoom();
        map.setZoomAndCenter(currentZoom != zoomLevel ? currentZoom : zoomLevel, lnglat);
        marker.setPosition(lnglat);
    }

以上就是引入地图的所有代码啦

我就知道你个CV仔会看这里
完整代码

import React, { Component } from 'react'
import { Form, Input } from 'antd';
import axios from 'axios';
import myScript  from 'scriptjs'
const amapKey = '8434182*****************ce12c32b508';//申请的key
const gaodeMapSdk = 'https://webapi.amap.com/maps?v=1.4.2&key=' + amapKey;
var map = null;//用于实例化地图
var marker = null;//用于实例化定位图标
var geocoder = null;//用于获取经纬度
var zoomLevel = 15;//默认地图层级(放大缩小)
// lat纬度lng经度
export default class amapTest extends Component {
    formRef = React.createRef();
    constructor(props) {
        super(props)
        this.state = {
            isAmapShow: false,//控制输入提示弹窗显示
            addresList: []//用于接收输入提示列表
        }
    }
    // 渲染前
    componentWillMount() {
        if (!window.AMap && !(window.google && window.google.maps)) {
            myScript ([gaodeMapSdk], function (a, b) { })
        }
    }
    // 渲染后
    componentDidMount() {
        let _this = this;
        _this.listenerStorage();
    }
    //实例化地图
    listenerStorage = () => {
        let _this = this;
        if (window.AMap || (window.google && window.google.maps)) {
            if (window.AMap) {
                const latlngxy = ["116.397428","39.90923"];//默认地址 北京天安门
                map = new window.AMap.Map('container', {
                    resizeEnable: true,
                    center: latlngxy,
                    zoom: zoomLevel
                });
                //高德设置语言    ['en', 'zh_en', 'zh_cn']  
                map.setLang('zh_en');
                // 在新中心点添加 marker   
                marker = new window.AMap.Marker({
                    map: map,
                    position: latlngxy
                });
                map.on('click', function (e) {
                    window.AMap.service('AMap.Geocoder', function () {//回调函数  
                        //实例化Geocoder  
                        geocoder = new window.AMap.Geocoder({});
                        geocoder.getAddress(e.lnglat, function (status, result) {
                            let latlngs = [e.lnglat.lng, e.lnglat.lat]
                            const currentZoom = map.getZoom();
                            map.setZoomAndCenter(currentZoom != zoomLevel ? currentZoom : zoomLevel, latlngs);
                            marker.setPosition(e.lnglat);
                            //获取坐标或地名
                            axios.get('https://restapi.amap.com/v3/geocode/regeo?location=' + e.lnglat.lng + ',' + e.lnglat.lat + '&key=' + amapKey).then((res) => {
                                //根据地名获取经纬度
                                axios.get('https://restapi.amap.com/v3/geocode/geo?address=' + res.data.regeocode.formatted_address + '&key=' + amapKey).then((ress) => {
                                    // ress.data.geocodes[0].location //经纬度
                                    _this.formRef.current.setFieldsValue({
                                        addres: ress.data.geocodes[0].formatted_address
                                    })
                                })
                            })
                        })
                    })
                })
            }
            _this.setState({
                status: 1
            })
        } else {
            setTimeout(function () {
                _this.listenerStorage()
            }, 800)
        }
    }
    //关键字搜索
    phoneValidator = (_, value, callback) => {
        if (value) {
            this.setState({
                isAmapShow: true
            })
            axios.get('https://restapi.amap.com/v3/place/text?keywords=' + value + '&offset=20&key=' + amapKey).then((res) => {
                this.setState({
                    addresList: res.data.pois
                })
                return callback();
            })
        } else {
            this.setState({
                isAmapShow: false
            })
            return Promise.reject(new Error('请输入地址'));
        }

    }
    // 选择
    delFolder = (value, e) => {
        this.setState({
            isAmapShow: false
        })
        let lnglat = value.location.split(',')
        const currentZoom = map.getZoom();
        map.setZoomAndCenter(currentZoom != zoomLevel ? currentZoom : zoomLevel, lnglat);
        marker.setPosition(lnglat);
    }
    render() {
        return (
            <div>
                <Form style={{ width: '500px' }} ref={this.formRef}>
                    <Form.Item label="地址" name="addres" rules={[{ validator: this.phoneValidator }]}>
                        {/* <Form.Item> */}
                        <Input placeholder="请输入地址" autocomplete="off" allowClear />
                        {/* </Form.Item> */}
                    </Form.Item>
                </Form>
                <div id="container" style={{ width: '500px', height: '300px', position: 'relative' }}>
                    {this.state.isAmapShow ? <div style={{ width: '200px', height: '300px', background: '#fff', position: 'absolute', top: '0px', left: '0px' }}>
                        <ul className="addres_list" style={{ padding: '0px', height: '300px', overflowY: 'scroll' }}>
                            {
                                this.state.addresList.map((value, key) => {
                                    return (
                                        <li key={key} style={{
                                            listStyle: 'none', height: '30px', lineHeight: '30px', textIndent: '10px', borderBottom: '1px solid #ccc',
                                            overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap'
                                        }} onClick={this.delFolder.bind(this, value)}>{value.name}</li>
                                    )
                                }
                                )
                            }
                        </ul>
                    </div> : null}
                </div>
            </div>
        )
    }
}

对你有帮助的话别忘了点赞关注加转发(手动狗头)!!!

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值