Vue学习笔记-高德地图组件

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

准备工作:

高德开放平台,注册成为开发者。
高德开发者平台-应用.png

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

实现方式:

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

1:在index.html 中引入

<script type="text/javascript" src="http://webapi.amap.com/maps?v=1.4.6&key=你申请的高德appKey&plugin=AMap.Walking"></script>

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

相关资料:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容

  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    王喂马_阅读 6,441评论 1 77
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    小姜先森o0O阅读 9,395评论 0 72
  • 基于Vue的一些资料 内容 UI组件 开发框架 实用库 服务端 辅助工具 应用实例 Demo示例 element★...
    尝了又尝阅读 1,140评论 0 1
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    35eeabfa0772阅读 3,258评论 7 12
  • UI组件 element - 饿了么出品的Vue2的web UI工具套件 Vux - 基于Vue和WeUI的组...
    鲁大师666阅读 43,366评论 5 97