Vue学习笔记-高德地图组件
2019-03-07 本文已影响237人
赵客缦胡缨v吴钩霜雪明
公司之前一直使用的是百度地图组件,最近运营人员一直反映一个问题:有一些地区在百度地图上搜不到,地址搜索没有响应。我以为是地图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.png2.方式二
封装一个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相关资料: