美文网首页
vue 使用高德地图插件 vue-amap文章

vue 使用高德地图插件 vue-amap文章

作者: 东扯葫芦西扯瓜 | 来源:发表于2020-03-28 22:44 被阅读0次

    账号注册

    首先得成为高德地图开发者,也就是说你的拥有一个账号,当然有公司账号最好,没有就暂时自己先注册一个。

    注册好后,点开控制台,右上角创建一个新应用,选好你需要的环境,vue的话估计基本都是web端吧,然后就可以看到你的开发需要的key了


    高德地图插件安装

    首先说明,这里示例项目使用vue-cli3脚手架,不熟悉的可以先去看看vue-cli3创建项目相关。

    npm安装vue-amap

    npm install vue-amap --save

    页面引入与组件配置

    我这里的项目因为多个地方都会用的地图,所以将地图这一块抽离出来做一个单独的组件,并且是全局组件,方便页面引用

    创建全局组件AMap

    创建全局地图组件文件AMap.vue以及全局组件配置文件globalComponents.js

    项目目录结构如图所示

    main.js页面引入vue-amap以及globalComponents.js

    import Vue from 'vue'

    import App from './App.vue'

    import router from './router'

    import store from './store'

    import globalComponents from './assets/commonJs/globalComponents'  //全局组件配置文件

    import VueAMap from 'vue-amap'; // 高德地图

    import {AMapKey} from './assets/commonJs/constDatas'//AMapKey是高德地图开发key,我这里放到了一个专门的文件管理,你也可以不必这样做。

    Vue.use(VueAMap)  //插件使用声明

    Vue.use(globalComponents)  //插件使用声明

    //下面是vue-amap初始化,请将AMapKey换成你自己的key

    VueAMap.initAMapApiLoader({

        key:AMapKey,

        plugin: ['AMap.Autocomplete', 'AMap.PlaceSearch', 'AMap.Scale', 'AMap.OverView', 'AMap.ToolBar', 'AMap.MapType', 'AMap.PolyEditor', 'AMap.CircleEditor', 'AMap.Geolocation', ],

        v: '1.4.4'

    })

    Vue.config.productionTip = false

    new Vue({

      router,

      store,

      render: h => h(App)

    }).$mount('#app')

    配置AMap为全局组件

    在globalComponents.js文件中

    import AMap from '../../globalComponents/AMap/AMap'; //高德地图组件

    export default {

      install(Vue) {

          Vue.component('AMap', AMap)

      }

    };

    AMap页面实现

    **这里强调一下,想要使用好vue-amap,首先得在页面引入AMap地图标签创建地图实例,后面才可以使用相应的API,有些小伙伴可能并不需要展示地图,只是想使用某个API,比如根据经纬度获取地址,所以在main.js中配置好后就迫不及待的去相应的页面来这么一段

    AMap.plugin(‘AMap.Geocoder’, ()=> {

    let geocoder = new AMap.Geocoder({

    // city 指定进行编码查询的城市,支持传入城市名、adcode 和 citycode

    city:citycode

    })

    geocoder.getAddress([lng,lat], (status, result)=> {

    })

    **

    然后你看到可能就是下面这种

    还有你可能直接在页面引入,比如这样 import AMap from ‘vue-amap’,然后你很可能看到下面这样的报错。

    其他废话不多说了,总之必须得先在html部分用标签创建好实例,其他API才可以使用。废话不多说,上代码,先看html部分

    <template>

        <div class="amapBox" :style="{height}">

            <el-amap class="amap-box" :vid="'amap-vue'" :plugin="plugin" :center="mapCenter" :events="events" ref="map">

                <el-amap-marker

                        vid="component-marker"

                        :position="markPosition"

                        :icon="require('../../assets/images/mapMark.png')"

                        :draggable="true"

                        :raiseOnDrag="true"

                        :events="markEvents"

                ></el-amap-marker>

            </el-amap>

        </div>

    </template>

    el-amap即vue-amap创建实例的标签,class不用说,vid照写就好,是地图组件id,另外plugin是地图插件配置,center是地图的中心位置,events是事件

    el-amap-marker是地图标记标签,其中position是标签位置,icon是标记图标,可以使用网络图片或者本地图片,本地图片请使用require引入,draggable表示是否可以拖动标记,events是事件

    <!--js部分-->

    <script>

        export default {

            name: 'AMap',

            //考虑到动态需求,允许默认中心点和地图高度从父组件传递来,如果不传递,则使用默认值

            props:{

                center:{

                    type:Array,

                    default:()=>{return [106.61994874,26.64158513]}

                },

                height:{

                    type:String,

                    default:'6rem'

                }

            },

            data() {

                return {

                    mapCenter: [],//地图中心坐标数组,因为可能会从父组件传递,所以初始为空,将会在created生命周期中赋值

                    loaded: false,

                    /*events是包含地图事件的对象,init是地图初始化时触发,moveeend地图拖动时触发,click点击地图触发,zoomchange地图缩放级别更改后触发*/

                    events: {

                        init:this.mapInit,

                        'moveend': this.moveend,

                        'zoomchange': this.zoomchange,

                        'click': this.mapClick

                    },

                    markEvents:{//标记事件

                        click:this.markClick, //标记点击触发

                        dragend:this.markDragend //标记拖动触发

                    },

                    plugin: [ //插件

                        {

                            pName: 'Geolocation', //定位插件

                            events: {

                                init:this.getGolocationInit  //定位初始化函数

                            }

                        },'Autocomplete','PlaceSearch','Scale','OverView','PolyEditor','ToolBar',

                    ],

                    markPosition:[106.61994874,26.64158513],//标记物位置

                    cityInfo:{},//当前城市信息

                }

            },

            methods: {

                // 地图初始化函数

                mapInit(o){

                    // console.log(o.getCenter())

                    // console.log(this.$refs.map.$$getInstance())

                    o.getCity(result => {

                        this.cityInfo=result

                        this.$emit('getInitCityInfo',result)//获取初始化城市信息并传递给父组件

                    })

                },

                //点图点击事件

                async mapClick(e){

                    // console.log(e)

                    let {lng,lat} =e.lnglat

                    this.markPosition=[lng,lat]

                    this.$emit('getMapClickLngLat',[lng,lat])//获取点击地图点经纬度并传递给父组件

                    let addressInfo=await this.getAddressFromLngLat(lng,lat)

                    this.$emit('getAddressInfo',addressInfo)//点击地图获取地址并传递给父组件

                },

                //定位初始化

                getGolocationInit(o){

                    o.getCurrentPosition((status, result) => {

                        if (result && result.position) {

                            // console.log(result)

                            let {position,addressComponent,formattedAddress}=result

                            let {lng,lat}=position

                            this.mapCenter = [lng, lat]

                            this.markPosition = [lng, lat]

                            this.loaded = true;

                            this.$nextTick();

                            this.$emit('getGolocationInitAddressInfo',{ //获取定位信息并传递给父组件

                                addressComponent,

                                formattedAddress,

                                lng,

                                lat

                            })

                        }

                    });

                },

                //地图移动

                moveend(){

                },

                //地图比例改变

                zoomchange(){

                },

                markClick(){

                    // alert('xxx')

                },

                //根据经纬度获取地址

                getAddressFromLngLat(lng,lat){

                    let {cityInfo}=this

                    let {citycode}=cityInfo

                    return new Promise((resolve,reject)=>{

                        AMap.plugin('AMap.Geocoder', ()=> {

                            let geocoder = new AMap.Geocoder({

                                // city 指定进行编码查询的城市,支持传入城市名、adcode 和 citycode

                                city:citycode

                            })

                            geocoder.getAddress([lng,lat], (status, result)=> {

                                // console.log(status,result)

                                if (status === 'complete' && result.info === 'OK') {

                                    // result为对应的地理位置详细信息

                                    let {addressComponent,formattedAddress}=result.regeocode

                                    let {province,city,district,township}=addressComponent

                                    resolve({

                                        formattedAddress,

                                        province,

                                        city,

                                        district,

                                        township

                                    })

                                }

                            })

                        })

                    })

                },

                //标记点拖动结束

                async markDragend(e){

                    let {lng,lat} =e.lnglat

                    let addressInfo=await this.getAddressFromLngLat(lng,lat)

                  this.$emit('getAddressInfo',addressInfo)//拖动结束获取地址并传递给父组件

                },

                //通过地址查询经纬度

                getLngLatFromAddress(address){

                    if(!address) return

                    let {cityInfo}=this

                    let {citycode}=cityInfo

                    return new Promise((resolve,reject)=>{

                        AMap.plugin('AMap.Geocoder', ()=> {

                            let geocoder = new AMap.Geocoder({

                                city:citycode

                            })

                            geocoder.getLocation(address, (status, result) =>{

                                let lngLatArr=[]

                                let {geocodes=[]} = result

                                geocodes.forEach((item,index)=>{

                                    let {lng,lat}=item.location

                                    lngLatArr.push({lng,lat})

                                })

                                resolve(lngLatArr)

                            })

                        })

                    })

                },

                //搜索提示

                getSearchAddresList(keyword){

                    let {cityInfo}=this

                    let {citycode}=cityInfo

                    return new Promise((resolve,reject)=>{

                        AMap.plugin('AMap.Autocomplete', ()=>{

                            // 实例化Autocomplete

                            let autoOptions = {

                                //city 限定城市,默认全国

                                city: citycode

                            }

                            let autoComplete= new AMap.Autocomplete(autoOptions);

                            autoComplete.search(keyword, (status, result)=> {

                                // 搜索成功时,result即是对应的匹配数据

                                if (status === 'complete' && result.info === 'OK') {

                                    // result为对应的地理位置详细信息

                                    resolve(result.tips)

                                }

                            })

                        })

                    })

                }

            },

            created(){

                this.mapCenter=this.center

            },

            mounted() {

            }

        }

    </script>

    下面css部分,高德地图组件本身默认没有宽高,需要继承父级的宽高,所以需要给el-map标签父级设置宽高

    <style scoped lang="less">

        .amapBox{

            width:100%;

        }

    </style>

    地图组件已经完成,可以愉快的调用了

    父组件调用AMap组件

    AMap已经配置为全局组件,所以本页面可以直接使用,不再需要引入和注册组件

    <template>

        <div class="mapBox columnStart">

            <div class="mapSearchBox rowStart">

                <img src="../../../assets/images/search.png" class="searchIcon"/>

                <input placeholder="搜索地点" class="mapInput" v-model="searchName" @input="searchAddress"/>

            </div>

            <AMap @getAddressInfo="getAddressInfo" ref="amapComponent"/>

            <ul class="mapAddressBox">

                <li class="rowBtween mapAddressLi" v-for="(address,index) in addresses" :key="index" @click="chooseAddress(index)">

                    <div class="addressBox columnStart">

                        <div class="addressName">{{address.name}}</div>

                        <span class="detailAddress gray999">{{address.formattedAddress}}</span>

                    </div>

                    <van-icon name="success" color="#4491FA" size="18" v-if="activeIndex===index"/>

                </li>

            </ul>

        </div>

    </template>

    <script>

        export default {

            name: 'ChooseAddress',

            data() {

                return {

                    routerData:{},//路由跳转携带点数据

                    activeIndex:null,//选择点地址下标

                    addresses:[],//搜索出来的地址

                    searchName:'',//要搜索的地址名称

                    fromRouteName:'',//来源路由名称

                }

            },

            methods: {

                //选择地址

                chooseAddress(index){

                    this.activeIndex=index

                },

                //获取地址

                getAddressInfo(addressInfo){

                    // console.log(addressInfo)

                    let {formattedAddress,province,city,district,township}=addressInfo

                    this.addresses=[

                        {

                            name:`${township}(${city}${district})`,

                            formattedAddress

                        }

                    ]

                    this.activeIndex=0

                },

                //搜索地址

                async searchAddress(){

                    let {searchName}=this

                  let addressInfos=await this.$refs.amapComponent.getSearchAddresList(searchName)

                    // console.log(addressInfos)

                    this.addresses=[]

                    for(let i=0;i<addressInfos.length;i++){

                        this.addresses.push({

                            name:addressInfos[i].name,

                            formattedAddress:`${addressInfos[i].district}${addressInfos[i].address}`

                        })

                    }

                },

                //确定选择地址

                sureChooseAddress(){

                    let {addresses,activeIndex,routerData,fromRouteName}=this

                    routerData.mapAddressInfo=addresses[activeIndex]

                    this.$globalMethods.batchDispatchFun([

                        {fun:'changeShowRightBtn',data:false},

                    ])

                    this.$router.replace({

                        name:fromRouteName,

                        params:{

                            routerData,

                        }

                    })

                }

            },

            mounted() {

                let {topTitle='地图',routerData={},fromRouteName=''} = this.$route.params

                this.routerData=routerData

                this.fromRouteName=fromRouteName

                this.$globalMethods.batchDispatchFun([

                    {fun:'changeTopTitle',data:topTitle},

                ])

            }

        }

    </script>

    <style scoped lang="less">

        .mapBox{

            background:#f5f5f5;

            .mapSearchBox{

                width:7.1rem;

                height:.7rem;

                margin:.2rem auto;

                background:#ffffff;

                border:solid .01rem #cccccc;

                -webkit-border-radius: .1rem;

                -moz-border-radius: .1rem;

                border-radius: .1rem;

                padding:0 .2rem;

                .searchIcon{

                    width:.36rem;

                    height:.36rem;

                    margin-right:.2rem;

                }

                .mapInput{

                    width:6rem;

                    border:none;

                }

            }

            .mapAddressBox{

                padding:0.2rem 0 1rem .2rem;

                width:100%;

                background:#ffffff;

                height:5rem;

                overflow:auto;

                .mapAddressLi{

                    padding:.2rem 0.2rem .2rem 0;

                    border-bottom:solid .01rem #e6e6e6;

                    .addressBox{

                        align-items:flex-start;

                        .addressName{

                            max-width:6rem;

                            overflow:hidden;

                            -ms-text-overflow: ellipsis;

                            text-overflow: ellipsis;

                            white-space: nowrap;

                        }

                        .detailAddress{

                            margin-top:.1rem;

                            font-size:.24rem;

                            max-width:6rem;

                            overflow:hidden;

                            -ms-text-overflow: ellipsis;

                            text-overflow: ellipsis;

                            white-space: nowrap;

                        }

                    }

                }

            }

        }

    </style>

    ————————————————

    版权声明:本文为CSDN博主「前端小菜鸟crazy  yang」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

    原文链接:https://blog.csdn.net/qq_41000974/article/details/105169669

    相关文章

      网友评论

          本文标题:vue 使用高德地图插件 vue-amap文章

          本文链接:https://www.haomeiwen.com/subject/qhxeuhtx.html