1、需求引入
最近需要封装一个map组件,需要能够实现自动获取经纬度定位以及给出对应的标记点,支持搜索不同的地区,我选择的处理方式是使用百度地图的API,大致的处理方法以及属性API中都涵盖了,因此也不需要做什么很特别的处理,我在地图加载渲染的过程中添加了加载动画,这样体验上更好一点。
2、npm安装
npm install vue-baidu-map --save
3、使用
在main.js中引入百度地图相关文件
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store/index'
import BaiduMap from 'vue-baidu-map'
Vue.config.productionTip = false
import './checkRouter'
Vue.use(BaiduMap, {
// ak 是在百度地图开发者平台申请的密钥
ak: '6EZdork********************' //这是我的百度map的ak
})
new Vue({
router,
store,
// i18n,
render: h => h(App)
}).$mount('#app')
4、开始封装
首先在公共组件文件components目录下创建一个vue文件,我这边创建的是positionmap.vue
我的positionmap.vue这个组件中的具体实现内容如下:
<template>
<div>
<Modal
@on-cancel="cancel"
v-model="showMapComponent"
width="1200"
:closable="false"
:mask-closable="false"
>
<div style="margin-bottom: 20px">
经度:<Input v-model="center.lng" style="width: 200px"></Input>
纬度:<Input v-model="center.lat" style="width: 200px"> </Input>
<Poptip trigger="focus">
地址:
<Input v-model="address" style="width: 200px" />
<div slot="content">{{ formatNumber }}</div>
</Poptip>
</div>
<baidu-map
class="bm-view"
ak="6EZdorkf6kz2p7GPPHdhlDZ7xTuclD0c"
:center="{ lng: center.lng, lat: center.lat }"
:zoom="17"
:scroll-wheel-zoom="true"
@ready="handler"
@click="getClickInfo"
@moving="syncCenterAndZoom"
@moveend="syncCenterAndZoom"
@zoomend="syncCenterAndZoom"
>
<bm-view style="width: 100%; height: 500px"></bm-view>
<bm-marker
:position="{ lng: center.lng, lat: center.lat }"
:dragging="true"
animation="BMAP_ANIMATION_BOUNCE"
>
<Row class="loadSpin" v-if="loading">
<Col class="demo-spin-col" span="24">
<Spin fix>
<Icon
type="ios-loading"
size="22"
class="demo-spin-icon-load"
></Icon>
<div>Loading</div>
</Spin>
</Col>
</Row>
<bm-info-window :show="show">当前坐标</bm-info-window>
</bm-marker>
<bm-control :offset="{ width: '10px', height: '10px' }">
<bm-auto-complete v-model="keyword" :sugStyle="{ zIndex: 999999 }">
<input
type="text"
placeholder="请输入搜索关键字"
class="serachinput"
/>
</bm-auto-complete>
</bm-control>
<bm-local-search
:keyword="keyword"
:auto-viewport="true"
style="width: 0px; height: 0px; overflow: hidden"
>
</bm-local-search>
<bm-navigation anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-navigation>
</baidu-map>
<div slot="footer" style="margin-top: 0px">
<Button @click="cancel" style="width: 60px; height: 36px">取消 </Button>
<Button
type="primary"
style="width: 60px; height: 36px"
@click="confirm"
>确定</Button
>
</div>
</Modal>
</div>
</template>
<script>
export default {
data: function () {
return {
showMapComponent: this.value,
keyword: "",
address: "",
loading: false,
show: false,
mapStyle: {
width: "100%",
height: this.mapHeight + "px",
},
center: { lng: "", lat: "" },
zoom: 15,
};
},
watch: {
value: function (currentValue) {
this.showMapComponent = currentValue;
if (currentValue) {
this.keyword = "";
}
},
},
props: {
value: Boolean,
mapHeight: {
type: Number,
default: 500,
},
},
computed: {
formatNumber() {
if (this.address === "") return "";
function parseNumber(str) {
const re = /(?=(?!)(d{3})+$)/g;
return str.replace(re, ",");
}
return parseNumber(this.address);
},
},
methods: {
//地图点击事件。
getClickInfo(e) {
var gc = new BMap.Geocoder();
let _this = this;
gc.getLocation(e.point, function (rs) {
var addComp = rs.addressComponents;
console.log(rs.address); //地址信息
_this.address = rs.address;
});
this.center.lng = e.point.lng;
this.center.lat = e.point.lat;
},
syncCenterAndZoom(e) {
setTimeout(() => {
this.show = false;
}, 10000);
if (this.center.lng) {
this.loading = false;
} else {
this.loading = true;
}
this.zoom = e.target.getZoom();
},
//确认
confirm: function () {
this.showMapComponent = false;
// 将map-confirm事件传出,给父组件
this.$emit("map-confirm", this.center);
},
//取消
cancel: function () {
this.showMapComponent = false;
// 将map-cancel事件传出,给父组件
this.$emit("map-cancel", this.showMapComponent);
},
//自动定位
handler({ BMap, map }) {
const that = this;
// 获取自动定位方法
var geolocation = new BMap.Geolocation();
// 获取自动定位获取的坐标信息
geolocation.getCurrentPosition(
function (r) {
that.center.lng = r.longitude;
that.center.lat = r.latitude;
},
{ enableHighAccuracy: true }
);
},
},
};
</script>
//我个人的相关样式代码
<style scoped>
.serachinput {
color: #333;
line-height: normal;
font-family: "Microsoft YaHei", Tahoma, Verdana, SimSun;
font-style: normal;
font-variant: normal;
font-size-adjust: none;
font-stretch: normal;
font-weight: normal;
margin-top: 0px;
margin-bottom: 0px;
margin-left: 0px;
padding-top: 4px;
padding-right: 4px;
padding-bottom: 4px;
padding-left: 4px;
font-size: 15px;
outline-width: medium;
outline-style: none;
outline-color: invert;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
text-shadow: 0px 1px 2px #fff;
background-attachment: scroll;
background-repeat: repeat-x;
background-position-x: left;
background-position-y: top;
background-size: auto;
background-origin: padding-box;
background-clip: border-box;
background-color: rgb(255, 255, 255);
margin-right: 8px;
border-top-color: #ccc;
border-right-color: #ccc;
border-bottom-color: #ccc;
border-left-color: #ccc;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-top-style: solid;
border-right-style: solid;
border-bottom-style: solid;
border-left-style: solid;
}
.demo-spin-icon-load {
animation: ani-demo-spin 1s linear infinite;
}
@keyframes ani-demo-spin {
from {
transform: rotate(0deg);
}
50% {
transform: rotate(180deg);
}
to {
transform: rotate(360deg);
}
}
/deep/.demo-spin-col {
height: 0px;
position: relative;
border: 1px solid #eee;
}
/deep/ .ivu-spin-fix {
position: absolute;
top: -501px;
left: -17px;
z-index: 8;
width: 1200px;
height: 505px;
background-color: rgba(255, 255, 255, 0.9);
}
</style>
5、父组件调用使用positionmap.vue组件
<FormItem label="经纬度:">
<Row>
<Col span="10">
<FormItem prop="lon">
<Input :value.sync="formValidate.lon">
<span slot="prepend">经度</span>
</Input>
</FormItem>
</Col>
<Col span="9" style="margin-left: 10px">
<FormItem prop="lat">
<Input :value.sync="formValidate.lat">
<span slot="prepend">维度</span>
</Input>
</FormItem>
</Col>
<Col span="2" offset="1">
<FormItem>
<Button type="success" @click="getLocation">定位</Button>
</FormItem>
</Col>
</Row>
</FormItem>
<Positionmap :value="flag" @map-confirm="mapConfirm" @map-cancel="mapCancel"></Positionmap>
import Positionmap from "@/components/baiduMap/positionmap";
data(){
return {
flag: false,
}
}
//确定位置
mapConfirm(val) {
this.formValidate.lon = val.lng;
this.formValidate.lat = val.lat;
this.flag = false;
},
//点击取消
mapCancel() {
this.flag = false;
},
// 打开定位
getLocation() {
this.flag = true;
}