效果如下
·
引入地图qqmap
刚开始我是直接用 npm install qqmap
,但是好像只有v1版本的,我需要用v2版本的,所以直接使用script标签加载API服务。
文件:/public/index.html
<script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&key=YOUR_KEY"></script>
v参数是引用的版本号,目前腾讯地图提供两个版本,分别是v=1,v=2.exp,推荐使用2.exp,可以获得最新最快的支持。key参数YOUR_KEY是Key鉴权中申请的key。
参考文档:# 腾讯位置服务API #
·
创建自定义组件
文件:/components/MapSelect.vue
<template>
<el-dialog
title="选择地址"
:visible.sync="isShowDialog"
width="1000px"
top="50px">
<div class="search">
<el-input placeholder="请输入搜索地址信息" v-model="keyword" clearable>
<el-button slot="append" icon="el-icon-search" @click="searchAddress"></el-button>
</el-input>
</div>
<div id="mapContainer" style="width: 100%; height: 350px"></div>
<div class="address">
<span>当前选点:</span>
<b>{{nowAddress ? (nowAddress.addressComponents.province + nowAddress.addressComponents.city + nowAddress.addressComponents.district + nowAddress.addressComponents.streetNumber) : '尚未选点'}}</b>
<el-button v-if="nowAddress" @click="selectAddress(nowAddress, 1)" type="text">【确认选择】</el-button>
</div>
<el-table
highlight-current-row
:data="nearPointList"
height="300"
style="width: 100%"
class="table"
>
<el-table-column prop="address" label="附近推荐地点">
<template slot-scope="scope">
{{scope.row.address}}{{scope.row.name}}
</template>
</el-table-column>
<el-table-column label="操作" width="100" align="center">
<template slot-scope="scope">
<el-button @click.native.prevent="selectAddress(scope.row, 2)" type="text">确认选择</el-button>
</template>
</el-table-column>
</el-table>
</el-dialog>
</template>
<script>
export default {
data() {
return {
keyword: '', // 搜索关键词
nearPointList: [], // 附近地址
isShowDialog: false, // 是否显示弹窗
markersArray: [],
geocoder: null,
nowAddress: null, // 选择的地点
geocoderLocation: null,
};
},
mounted() {
},
methods: {
// 搜索地址
searchAddress() {
if (!this.keyword) {
return this.$message.error("请输入搜索地址信息");
}
this.setLocationByAddress(this.keyword);
},
// 初始化地图
initMap() {
let that = this;
let latLon = new qq.maps.LatLng(39.916527, 116.397128);
var map = new qq.maps.Map(document.getElementById("mapContainer"), {
zoom: 13,
center: latLon,
mapTypeId: qq.maps.MapTypeId.ROADMAP,
});
var listener = qq.maps.event.addListener(map, 'click', function(event) {
that.setLocationByLatLng(
event.latLng.getLat(),
event.latLng.getLng()
);
});
// 经纬度解析类回调函数
this.geocoder = new qq.maps.Geocoder({
complete: function (result) {
console.log(result.detail);
that.nowAddress = result.detail;
that.nearPointList = result.detail.nearPois;
map.setCenter(result.detail.location);
// 标记点
let marker = new qq.maps.Marker({
map: map,
position: result.detail.location,
});
that.markersArray.push(marker);
if (that.markersArray.length > 1) {
for (let i = 0; i < that.markersArray.length - 1; i++) {
that.markersArray[i].setMap(null); // 清除标记
}
}
},
});
// 地址解析回调函数
that.geocoderLocation = new qq.maps.Geocoder({
complete: function (result) {
// 查找附近的点
let latLng = new qq.maps.LatLng(
result.detail.location.lat,
result.detail.location.lng
);
that.geocoder.getAddress(latLng);
},
});
},
// 选择地址事件
selectAddress(item, type) {
if(type === 1) {
let addressInfo = item.addressComponents;
this.$emit(
"on-select",
addressInfo.province + addressInfo.city + addressInfo.district + addressInfo.streetNumber,
item.location.lat,
item.location.lng
);
this.isShowDialog = false;
}
if(type === 2) {
this.$emit(
"on-select",
item.address + item.name,
item.latLng.lat,
item.latLng.lng
);
this.isShowDialog = false;
}
},
// 显示地图
show() {
this.isShowDialog = true;
setTimeout(() => {
this.keyword = '';
this.initMap();
})
},
// 根据地址信息进行定位
setLocationByAddress(address) {
setTimeout(() => {
this.geocoderLocation.getLocation(address);
})
},
// 根据经纬度进行定位
setLocationByLatLng(lat, lng) {
setTimeout(() => {
let latLng = new qq.maps.LatLng(lat, lng);
this.geocoder.getAddress(latLng);
})
},
},
};
</script>
<style scoped lang="scss">
.search {
margin-bottom: 15px;
margin-top: -20px;
}
.address {
margin-top: 15px;
margin-bottom: 10px;
.el-button {
padding: 0;
}
}
.table {
.el-button {
padding: 0;
}
}
</style>
·
页面调用
<template>
<div>
<el-input placeholder="请选择地址" v-model="mainForm.address" readonly>
<el-button slot="append" icon="el-icon-location" @click="openMap()"></el-button>
</el-input>
<MapSelect ref="ms" @on-select="selectAddress" />
</div>
</template>
<script>
import MapSelect from '@/components/Common/MapSelect'
export default {
components: {
MapSelect
},
data() {
return {
mainForm: {
address: '',
lat: '',
lng: '',
},
}
},
methods: {
// 打开地图弹窗
openMap() {
this.$refs.ms.show();
// 根据省市区设置初始值
// this.$refs.ms.setLocationByAddress(this.mainForm.address);
// 根据经纬度设置初始值
this.$refs.ms.setLocationByLatLng(this.mainForm.lat, this.mainForm.lng);
},
// 地址选择后的回调函数
selectAddress(address, lat, lng) {
this.mainForm.address = address;
this.mainForm.lat = lat;
this.mainForm.lng = lng;
},
}
}
</script>