Vue学习笔记 高德地图组件

Posted by fsoooo Blog on March 10, 2018

公司之前一直使用的是百度地图组件,最近运营人员一直反映一个问题:有一些地区在百度地图上搜不到,地址搜索没有响应。我以为是地图API版本不对,更新了版本,这个问题还是存在。于是我就考虑换一个地图组件也解决这个问题,于是高德就成了我的第一选择。

准备工作:

高德开放平台,注册成为开发者。

高德开发者平台-应用.png

申请Key,我申请的是Web端(JS API),不同的API效果可能不一样。

实现方式:

一:引入 高德,web-sdk (两种方式)

1:在index.html 中引入

` `

2:安装vue-amap

Vue-amap基于Vue2.0的高德地图的地图组件。  

 cnpm install vue-amap --save
二.在webpack.base.conf.js加入
externals: {
    'AMap': 'AMap',
}
三.实例

1.方式一

<template>
    <div class="hello">
    <el-input id="keyword" name="input" placeholder="请输入您要定位的位置" v-model="input"></el-input>
    <div style="height:500px" id="container" tabindex="0"></div>
    </div>
</template>

<script>
    import AMap from 'AMap'

    export default {
        name: 'HelloWorld',
        data() {
            return {
                msg: 'hello',
                input: '',
            }
        },
        mounted() {
            this.init();
        },
        methods: {
            init: function () {
                let that = this;
                let map = new AMap.Map('container', {
                    center: [116.397428, 39.90923],
                    resizeEnable: true,
                    zoom: 10,
                    lang: 'ch',
                    keyboardEnable: true
                });
                AMap.plugin('AMap.Geolocation', function () {
                    var geolocation = new AMap.Geolocation({
                        // 是否使用高精度定位,默认:true
                        enableHighAccuracy: true,
                        // 设置定位超时时间,默认:无穷大
                        timeout: 10000,
                        // 定位按钮的停靠位置的偏移量,默认:Pixel(10, 20)
                        buttonOffset: new AMap.Pixel(10, 20),
                        // 定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
                        zoomToAccuracy: true,
                        // 定位按钮的排放位置, RB表示右下
                        buttonPosition: 'RB'
                    })
                    geolocation.getCurrentPosition()

                    AMap.event.addListener(geolocation, 'complete', (e) => {
                        console.log(e) // 定位成功之后做的事
                        // 定位成功之后再定位处添加一个marker
                        var marker = new AMap.Marker({
                            position: e.position, // (e.position)--->定位点的点坐标, position ---> marker的定位点坐标,也就是marker最终显示在那个点上,
                            icon: '', // marker的图标,可以自定义,不写默认使用高德自带的
                            map: map,  // map ---> 要显示该marker的地图对象
                        });
                    });
                    AMap.event.addListener(geolocation, 'error', (e) => {
                        console.log(e) // 定位失败做的事
                    })
                })
                AMap.plugin(['AMap.Autocomplete', 'AMap.PlaceSearch'], function () {
                    var autoOptions = {
                        city: "北京", //城市,默认全国
                        input: 'keyword',//使用联想输入的input的id
                    };
                    var autocomplete = new AMap.Autocomplete(autoOptions);
                    var placeSearch = new AMap.PlaceSearch({
                        city: '北京',
                        map: map
                    })
                    AMap.event.addListener(autocomplete, "select", function (e) {
                        //TODO 针对选中的poi实现自己的功能
                        placeSearch.setCity(e.poi.adcode);
                        placeSearch.search(e.poi.name)
                    });
                });
                AMap.plugin(['AMap.ToolBar', 'AMap.Scale'], function () {
                    map.addControl(new AMap.ToolBar())
                    map.addControl(new AMap.Scale())
                })
            },
        }
    }
</script>

效果如图:

方式一.1.png

方式一.2.png

2.方式二

封装一个mapDrag的组件

<template>
    <div class="m-map">
        <div class="search" v-if="placeSearch">
            <div class="el">
                <el-input placeholder="请输入您要定位的位置" v-model="searchKey">
                    <el-button @click="handleSearch" icon="el-icon-location" slot="append">搜索</el-button>
                </el-input>
            </div>
            <div id="js-result" v-show="searchKey" class="result"></div>
        </div>
        <div id="js-container" class="map">地图加载中...</div>
    </div>
</template>

<script>
    import remoteLoad from '@/utils/remoteLoad.js'
    import {MapCityName, MapKey} from '@/config/env'

    export default {
        props: ['lat', 'lng'],
        data() {
            return {
                searchKey: '',
                placeSearch: null,
                dragStatus: false,
                AMapUI: null,
                AMap: null
            }
        },
        watch: {
            searchKey() {
                if (this.searchKey === '') {
                    this.placeSearch.clear()
                }
            }
        },
        methods: {
            // 搜索
            handleSearch() {
                if (this.searchKey) {
                    this.placeSearch.search(this.searchKey)
                }
            },
            // 实例化地图
            initMap() {
                // 加载PositionPicker,loadUI的路径参数为模块名中 'ui/' 之后的部分
                let AMapUI = this.AMapUI = window.AMapUI
                let AMap = this.AMap = window.AMap
                AMapUI.loadUI(['misc/PositionPicker'], PositionPicker => {
                    let mapConfig = {
                        zoom: 16,
                        cityName: MapCityName,
                        mapStyle: 'amap://styles/55fec7fda8c3e5aeb7b79a2398ba494a', //设置地图的显示样式
                    }
                    if (this.lat && this.lng) {
                        mapConfig.center = [this.lng, this.lat]
                    }
                    let map = new AMap.Map('js-container', mapConfig)
                    // 加载地图搜索插件
                    AMap.service('AMap.PlaceSearch', () => {
                        this.placeSearch = new AMap.PlaceSearch({
                            pageSize: 5,
                            pageIndex: 1,
                            citylimit: true,
                            city: MapCityName,
                            map: map,
                            panel: 'js-result'
                        })
                    })
                    // 启用工具条
                    AMap.plugin(['AMap.ToolBar'], function () {
                        map.addControl(new AMap.ToolBar({
                            position: 'RB'
                        }))
                    })
                    // 创建地图拖拽
                    let positionPicker = new PositionPicker({
                        mode: 'dragMap', // 设定为拖拽地图模式,可选'dragMap'、'dragMarker',默认为'dragMap'
                        map: map // 依赖地图对象
                    })
                    // 拖拽完成发送自定义 drag 事件
                    positionPicker.on('success', positionResult => {
                        // 过滤掉初始化地图后的第一次默认拖放
                        if (!this.dragStatus) {
                            this.dragStatus = true
                        } else {
                            this.$emit('drag', positionResult)
                        }
                    })
                    // 启动拖放
                    positionPicker.start()
                })
            }
        },
        async created() {
            // 已载入高德地图API,则直接初始化地图
            if (window.AMap && window.AMapUI) {
                this.initMap()
                // 未载入高德地图API,则先载入API再初始化
            } else {
                await remoteLoad(`https://webapi.amap.com/maps?v=1.4.7&key=${MapKey}`)
                await remoteLoad('https://webapi.amap.com/ui/1.0/main.js')
                this.initMap()
            }
        }
    }
</script>

<style lang="css">
    .m-map {
        min-width: 800px;
        min-height: 450px;
        position: relative;
        border: 0.5px solid #b2b2b2;
    }

    .m-map .map {
        width: 100%;
        height: 100%;
    }

    .m-map .search {
        position: absolute;
        top: 10px;
        left: 10px;
        width: 800px;
        z-index: 1;
    }

    .m-map .search .el {
        width: 400px;
        border: 1px solid #ccc;
        line-height: 20px;
        padding: 5px;
        outline: none;
    }

    .m-map .result {
        max-height: 300px;
        max-width: 400px;
        overflow: auto;
        margin-top: 10px;
        z-index: 1;
    }
</style>

在需要使用的地方调用

<template>
    <div id="app">
        <div class="head">
            <el-input placeholder="当前定位的位置"  v-model="dragData.address" readonly class="el-input">
                <el-button @click="submit" icon="el-icon-location" slot="append">确认位置</el-button>
            </el-input>
        </div>
        <div class="m-part">
            <mapDrag @drag="dragMap" class="mapbox"></mapDrag>
        </div>
    </div>
</template>

<script>
    import mapDrag from "@/components/GaoDeMap/mapDrag"
    import {getStore, removeStore, setStore} from "@/config/mUtils"

    export default {
        name: 'app',
        components: {
            mapDrag
        },
        data() {
            return {
                dragData: {
                    lng: null,
                    lat: null,
                    address: null,
                    nearestJunction: null,
                    nearestRoad: null,
                    nearestPOI: null
                },
                requestData: {
                    lon: null,
                    lat: null,
                    map_search:null,
                    address: null,
                }
            }
        },
        methods: {
            dragMap(data) {
                console.log(data);
                this.dragData = {
                    lng: data.position.lng,
                    lat: data.position.lat,
                    address: data.address,
                    nearestJunction: data.nearestJunction,
                    nearestRoad: data.nearestRoad,
                    nearestPOI: data.nearestPOI
                }
            },
            submit() {
                console.log(this.dragData);
                this.requestData.lat = this.dragData.lat;
                this.requestData.lon = this.dragData.lng;
                this.requestData.address = this.dragData.address;

                if (typeof (this.requestData.lat) == "undefined" && typeof (this.requestData.lon) == "undefined") {
                    this.requestData.lon = 116.500782;
                    this.requestData.lat = 39.940956;
                    this.requestData.map_search = '智驿信息';
                    this.requestData.address = '北京市朝阳区国兴观湖国际-1座';
                }
                if (this.requestData.lat == undefined && this.requestData.lon == undefined) {
                    this.requestData.lon = 116.500748;
                    this.requestData.lat = 39.941108;
                    this.requestData.map_search = '智驿信息';
                    this.requestData.address = '北京市朝阳区国兴观湖国际-1座';
                }
                if (this.requestData.lat < 1 || this.requestData.lon < 1) {
                    this.requestData.lon = 116.500748;
                    this.requestData.lat = 39.941108;
                    this.requestData.map_search = '智驿信息';
                    this.requestData.address = '北京市朝阳区国兴观湖国际-1座';
                }
                setStore('location', this.requestData);
                this.$emit("close", false)
            },
        }
    }
</script>

<style>
    body {
        margin: 0;
        font-family: "微软雅黑 Light";
    }

    .head .el-input {
        max-width: 800px;
    }


    .m-part {
        margin-bottom: 30px;
        margin-top: 20px;
    }

    .m-part::after {
        content: '';
        display: block;
        clear: both;
    }

    .m-part .title {
        font-size: 30px;
        line-height: 60px;
        margin-bottom: 10px;
        color: #333;
    }

    .m-part .mapbox {
        width: 600px;
        height: 400px;
        margin-bottom: 20px;
        float: left;
    }
</style>

效果如图:

方式二.2.png

方式二.1.png

相关资料: