Vue中使用高德地图

在Vue中使用高德地图,包括标记、搜索、自动补全功能。(不使用vue-amap

引入

/idnex.html:

1
<script type="text/javascript" src="http://webapi.amap.com/maps?v=1.4.10&key=3bcadc9fa8870c7db8912575f009bdfb&plugin=AMap.Autocomplete,AMap.Geocoder,AMap.PlaceSearch"></script>

注意版本为1.4,低版本在Vue中会报错

key为自己的密钥。plugin后带的是插件

地图组件封装

模板:

1
2
3
4
5
6
7
8
9
10
<template>
<div class="map-engine">
<div class="search" v-show="mapFlag">
<p>请输入关键字:</p>
<input type="text" id="tipInput" style="width: 250px" v-model="searchInput">
</div>
<div id="container" class="container" v-show="mapFlag">
</div>
</div>
</template>

data:

1
2
3
4
5
6
7
8
9
10
11
12
13
data() {
return {
mapFlag: false, // 是否显示地图
map: null, // 地图示例
marker: null, // 标记
searchInput: '', // 搜索
markers: [], // 搜索产生的多个标记
lng: '',
lat: '',
address: '',
currentPositionId: '' //当前的位置Id
};
},

props:

1
2
3
4
5
6
7
8
9
10
props: {
locationObj: {
type: Object,
default: () => ({
address: '当前位置',
lng: '',
lat: ''
})
}
},

初始化时,生成地图实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
mounted() {
// 忽略eslint的报错
/* eslint-disable no-undef */
window.map = this.map = new AMap.Map('container', {
resizeEnable: true,
dragEnable: true,
keyboardEnable: false,
doubleClickZoom: true,
zoom: 15
});

// 绑定点击事件
this.map.on('click', this.clickHandler);

// 搜索框
let auto = new AMap.Autocomplete({
input: 'tipInput'
});
let placeSearch = new AMap.PlaceSearch({
map: ''
});
//监听地名的选择
AMap.event.addListener(auto, 'select', e => {
placeSearch.setCity(e.poi.adcode); // 设置城市的 编码
// 地图定位城市
if (e.poi && e.poi.location) {
this.map.setZoom(18);
this.map.setCenter(e.poi.location);
}
// 查询位置 并添加maker
placeSearch.search(e.poi.name, (status, result) => {
if (status === 'complete' && result.info === 'OK') {
for (let h = 0; h < result.poiList.pois.length; h++) {
//返回搜索列表循环绑定marker
let position = result.poiList.pois[h]['location']; //经纬度
let address = result.poiList.pois[h]['address']; //地址
let marker = new AMap.Marker({
map: this.map,
position: position
});
this.markers.push(marker);
marker.extData = {
getLng: position['lng'],
getLat: position['lat'],
address: address
};
marker.on('click', e => {
let addressObj = {
address: e.target.extData.address,
lng: position['lng'],
lat: position['lat']
};
this.changeAddress(addressObj);
});
}
}
});
});
},

methods:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// 获取地图实例
getMap: function(found) {
var vm = this;
function checkForMap() {
if (vm.map) {
found(vm.map);
} else {
setTimeout(checkForMap, 50);
}
}
checkForMap();
},

// 监听地图 点击 事件
clickHandler(e) {
this.lng = e.lnglat.getLng();
this.lat = e.lnglat.getLat();
// 点击添加标记并显示地名
this.getMap(map => {
// 取消上一个标记
if (this.marker) {
map.remove(this.marker);
}
this.marker = new AMap.Marker({
position: new AMap.LngLat(e.lnglat.getLng(), e.lnglat.getLat())
});
// 添加标记
map.add(this.marker);
//获取地名
let lnglatXY = [e.lnglat.getLng(), e.lnglat.getLat()];
let geocoder = new AMap.Geocoder({
radius: 1000,
extensions: 'all'
});
geocoder.getAddress(lnglatXY, (status, result) => {
if (status === 'complete' && result.info === 'OK') {
let address = result.regeocode.formattedAddress;
let addressObj = {
address: address,
lng: e.lnglat.getLng(),
lat: e.lnglat.getLat()
};
this.changeAddress(addressObj);
}
});
});
},

// 展开、关闭地图
toggleMap(positionId) {
//清除所有的覆盖物
if (this.map) {
this.map.clearMap();
this.searchInput = '';
}

if (positionId === this.currentPositionId) {
this.currentPositionId = ''; //关闭地图
this.mapFlag = !this.mapFlag;
} else {
this.currentPositionId = positionId; //当前的 positionId
this.mapFlag = true;
}

if (this.mapFlag) {
// 如果带坐标,则回显
if (this.lng && this.lat) {
this.map.setZoomAndCenter(15, [this.lng, this.lat]);
this.getMap(map => {
this.marker = new AMap.Marker({
position: [this.lng, this.lat]
});
map.add(this.marker);
});
}
}
/*
else {
// 清除标记
if (this.marker) {
this.map.remove(this.marker);
}
if (this.markers.length) {
this.markers.forEach(item => {
this.map.remove(item);
});
}
// 清除搜索
this.searchInput = '';
}
*/
},

// 数据变换并抛出
changeAddress(addressObj) {
this.address = addressObj.address;
Object.assign(addressObj, { id: this.currentPositionId });
this.$emit('click-position', addressObj);
}

watch:

1
2
3
4
5
6
7
8
locationObj: {
handler: function() {
this.lat = this.locationObj.lat;
this.lng = this.locationObj.lng;
this.address = this.locationObj.address;
},
deep: true
}

destroyed;

1
2
3
4
destroyed() {
//销毁地图资源
this.map && this.map.destroy();
}

样式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<style scoped>
.map-engine {
position: relative;
}
.container {
width: 100%;
height: 600px;
}
.search {
border: 1px solid #ccc;
width: 270px;
height: 70px;
background-color: #fff;
position: absolute;
top: 30px;
left: 0;
z-index: 99;
padding-top: 8px;
padding-left: 8px;
}

.look {
pointer-events: none;
outline: none;
}
</style>

使用

模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<Row style="margin: 8px 0" v-for="item in positionList" :key="item.id">
<Col :span="12">
<Input type="text" :value="item.description" :readonly="true" />
</Col>
<Col :span="4">
<div class="map-op">
<a :class="{btn:true,choose:item.id === currentPositionId}" href="javascript:void(0)" @click="chooseMap(item.id)">选择地图</a>
|
<a class="btn" href="javascript:void(0)" @click="deleteHandler(item.id)">删除</a>
</div>
</Col>
</Row>

<MapEngine
ref="mapEngine"
:locationObj="currentGeoCord"
@click-position="positionHandler"
>
</MapEngine>
1
2
3
4
5
import MapEngine from '@/components/map-engine';

components: {
MapEngine
}

data:

1
2
3
4
5
6
7
positionList: [], // 表单外置获取的地理位置列表
currentPositionId: '', //当前操作的记录
currentGeoCord: {
address: '当地位置',
lng: '',
lat: ''
},

created:

初始时,获取已经有的位置列表

1
2
3
created() {
this.positionList=
}

methods:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// 打开、关闭地图
chooseMap(positionId) {
this.currentPositionId = positionId;
let positionRecord = this._getPositionById(positionId);
if (!positionRecord.latitude && !positionRecord.longitude) {
//恢复默认值
this.currentGeoCord = {
address: '当地位置',
lng: '',
lat: ''
};
} else {
this.currentGeoCord = {
address: positionRecord.description,
lat: positionRecord.latitude,
lng: positionRecord.longitude
};
}
// 让mapEngine里面的 watch先执行
this.$nextTick(() => {
this.$refs.mapEngine.toggleMap(positionId);
});
},

_getPositionById(positionId) {
return this.positionList.find(item => {
return item.id === positionId;
});
},

// 点击地图
positionHandler(geoCord) {
let record = this.positionList.find(item => {
return item.id === geoCord.id;
});
Object.assign(record, {
latitude: geoCord.lat,
longitude: geoCord.lng,
description: geoCord.address
});
},

// 删除位置
deleteHandler(positionId) {
this.positionList = this.positionList.filter(item => {
return item.id != positionId;
});
//关闭地图
if (this.currentPositionId === positionId) {
this.$refs.mapEngine.toggleMap(positionId);
this.currentPositionId = ''; // 清空选中的样式
}
},

// 添加位置
addHandler() {
this.positionList.push(this._getPositionRecord());
},

_getPositionRecord() {
let id = this.uniqueId++;
let positionRecord = {
id,
latitude: '',
longitude: '',
description: ''
};
return positionRecord;
},

效果: