展示效果:
开始前可以先去申请一个百度地图秘钥,点击
1.创建一个loadBMap.js,调用百度地址api js
/**
* 动态加载百度地图api函数
* @param {String} ak 百度地图AK,必传
*/
export default function loadBMap(ak) {
return new Promise(function(resolve, reject) {
if (typeof window.BMap !== 'undefined') {
resolve(window.BMap)
return true
}
window.onBMapCallback = function() {
resolve(window.BMap)
}
let script = document.createElement('script')
script.type = 'text/javascript'
script.src =
'http://api.map.baidu.com/api?v=3.0&ak=' + ak + '&callback=onBMapCallback'
script.onerror = reject
document.head.appendChild(script)
})
}
2.创建组件
<template>
<div>
<el-form label-width="80px">
<el-row>
<el-col :span="24">
<el-form-item label="搜索地址">
<el-autocomplete
style="width:100%;"
popper-class="autoAddressClass"
v-model="addressInfo.address"
:fetch-suggestions="querySearchAsync"
:trigger-on-focus="false"
placeholder="详细地址"
@select="handleSelect"
clearable>
<template slot-scope="{ item }">
<em class="el-icon-search fl mgr10" />
<div style="overflow:hidden;">
<div class="title">{
{ item.title }}</div>
<span class="address ellipsis">{
{ item.address }}</span>
</div>
</template>
</el-autocomplete>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div id="baidu-map-container" style="width: 100%; height: 400px;"></div>
<div slot="footer" class="dialog-footer mt10">
<el-button type="primary" @click="confirmSelect">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</div>
</template>
<script>
import loadBMap from '@/utils/loadBMap'
export default {
data() {
return {
searchAddresKeywords: "",
addressInfo: {
// 地址信息
longitude: "", // 经度
latitude: "", // 纬度
province: "", // 省
city: "", // 市
district: "", // 区
address: "", // 详细地址
},
openMap: false,
}
},
async mounted(){
await loadBMap('自己的秘钥') //加载引入BMap
this.initBaiduMap()
},
computed:{
},
methods:{
// 初始化百度地图
initBaiduMap() {
var that = this;
this.map = new BMap.Map("baidu-map-container", {enableMapClick:false}) //新建地图实例,enableMapClick:false :禁用地图默认点击弹框
var point = new BMap.Point(113.30765,23.12005);
this.map.centerAndZoom(point,19)
this.mk = new BMap.Marker(point,{enableDragging:true}) //创建一个图像标注实例,enableDragging:是否启用拖拽,默认为false
this.map.addOverlay(this.mk) //将覆盖物添加到地图中
this.mk.addEventListener('dragend', function(e){
that.getAddrByPoint(e.point) //拖拽结束后调用逆地址解析函数,e.point为拖拽后的地理坐标
})
var navigationControl = new BMap.NavigationControl({ //创建一个特定样式的地图平移缩放控件
anchor: BMAP_ANCHOR_TOP_RIGHT, //靠右上角位置
type: BMAP_NAVIGATION_CONTROL_SMALL //SMALL控件类型
})
this.map.addControl(navigationControl ) //将控件添加到地图
var geolocationControl = new BMap.GeolocationControl({anchor: BMAP_ANCHOR_BOTTOM_LEFT}) //创建一个地图定位控件
geolocationControl.addEventListener("locationSuccess", function(e){ //绑定定位成功后事件
that.getAddrByPoint(e.point) //定位成功后调用逆地址解析函数
});
geolocationControl.addEventListener("locationError",function(e){ //绑定定位失败后事件
console.log(e.message);
});
this.map.addControl(geolocationControl) //将控件添加到地图
this.map.addEventListener('click', function(e){ //给地图绑定点击事件
that.getAddrByPoint(e.point) //点击后调用逆地址解析函数
})
this.geolocation()
},
/**
* 浏览器定位函数
*/
geolocation() {
var that = this;
var geolocation = new BMap.Geolocation();
geolocation.getCurrentPosition(function(res){
if(this.getStatus() == BMAP_STATUS_SUCCESS){
that.getAddrByPoint(res.point) //当成功时,调用逆地址解析函数
} else {
console.log('failed'+this.getStatus()); //失败时,弹出失败状态码
}
},{enableHighAccuracy: true}) //enableHighAccuracy:是否要求浏览器获取最佳效果,默认为false
},
/** 逆向解析地址 point */
getAddrByPoint(point){
var that = this;
var geco = new BMap.Geocoder();
geco.getLocation(point, function(res){
console.log(res) //内容见下图
that.mk.setPosition(point) //重新设置标注的地理坐标
that.map.panTo(point) //将地图的中心点更改为给定的点
that.addressInfo.address = res.address; //记录该点的详细地址信息
that.addressInfo.addrPoint = point; //记录当前坐标点
})
},
querySearchAsync(str,cb){
var options = {
onSearchComplete: function(res){ //检索完成后的回调函数
var s = [];
if (local.getStatus() == BMAP_STATUS_SUCCESS){
for (var i = 0; i < res.getCurrentNumPois(); i ++){
s.push(res.getPoi(i));
}
cb(s) //获取到数据时,通过回调函数cb返回到<el-autocomplete>组件中进行显示
} else{
cb(s)
}
}
}
var local = new BMap.LocalSearch(this.map, options) //创建LocalSearch构造函数
local.search(str) //调用search方法,根据检索词str发起检索
},
handleSelect(item) {
this.addressInfo.address = item.address + item.title; //记录详细地址,含建筑物名
this.addressInfo.addrPoint = item.point; //记录当前选中地址坐标
this.map.clearOverlays() //清除地图上所有覆盖物
this.mk = new BMap.Marker(item.point) //根据所选坐标重新创建Marker
this.map.addOverlay(this.mk) //将覆盖物重新添加到地图中
this.map.panTo(item.point) //将地图的中心点更改为选定坐标点
},
/**
* 确认选择
*/
confirmSelect() {
this.$emit("confirmMapAddress", this.addressInfo);
this.openMap = false;
},
/**
* 取消选择
*/
cancel() {
this.$emit('cancelMap')
}
},
}
</script>
<style lang="scss" scoped>
// 防止地图自动完成的对象被遮挡
.tangram-suggestion {
z-index: 9999;
}
.autoAddressClass{
li {
.el-icon-search {margin-top:11px;}
.mgr10 {margin-right: 10px;}
.title {
text-overflow: ellipsis;
overflow: hidden;
}
.address {
line-height: 1;
font-size: 12px;
color: #b4b4b4;
margin-bottom: 5px;
}
}
}
</style>
3.调用组件
<div/ @click="show">打开地图</div>
<!-- 位置选择 -->
<el-dialog title="位置选择" :visible.sync="openMap" width="60%" append-to-body>
<baiduMap @cancelMap ="cancelMap" @confirmMapAddress="confirmMapAddress"/>
</el-dialog>
methods:{
/** 打开地图选择 */
show() {
this.openMap = true;
},
/** 确认地图地址 */
confirmMapAddress(addressInfo) {
this.ruleForm.addressInfo = addressInfo;
this.ruleForm.address= addressInfo.address
this.openMap = false
console.log('addressInfo',addressInfo)
},
// 关闭地图
cancelMap(){
this.openMap = false
},
}