引入问题
在vue的public下面的index.html中引入
<script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak=您的密钥"></script>
因为这是一个异步的过程,不能直接在组件中调用,需要把Bmap挂载到windows上
mounted() {
var that = this;
that.$nextTick(that.createMap(window.BMap));
},
createMap(BMap) {
// 百度地图API功能
let map = new BMap.Map("allmap"); // 创建Map实例
map.centerAndZoom(new BMap.Point(113.668868, 34.750949), 12); // 初始化地图,设置中心点坐标和地图级别
//添加地图类型控件
map.setCurrentCity("郑州"); // 设置地图显示的城市 此项是必须设置的
map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放
},
地图组件封装之后调用,出现地图只加载了一次,
问题是百度地图挂载显示的时候,需要获取Dom元素的id,如果存在的话就不去加载了, 解决办法:把定义的地图组件ID自定义,根据组件传值过改变
<template>
<div class="popup" v-show="showPopup" @mousewheel.prevent>
<div class="content">
<div class="map" :id="mapId || 'map'"></div>
<div class="input-auto">
<div class="label">{{title}}</div>
<div class="input-right">
<input class="input" v-model="formData.popAddress" :placeholder="placeholder" type="text" />
<div class="menu">
<div
class="menu-item"
v-for="(item,index) in list"
:key="index"
@mouseenter="enter(index)"
@mouseleave="leave"
>
<img class="icon" src=".././assets/circle.png" alt />
<div class="text">
<div class="name">{{ item.name }}</div>
<span class="addr">{{ item.address }}</span>
</div>
<div v-if="activeIndex==index" class="select" @click="selectChange(item)">选中</div>
</div>
</div>
</div>
</div>
<div class="close" @click="close">
<img src=".././assets/close.png" alt />
</div>
</div>
</div>
</template>
<script>
export default {
name: "Popup",
props: {
showDialog: Boolean,
title: String,
placeholder: String,
mapId: String
},
data() {
return {
formData: {
popAddress: "",
poplocation: ""
},
list: [],
activeIndex: -1,
showPopup: false,
searchTitle: "",
lag: "",
lat: ""
};
},
computed: {
address_change() {
return this.formData.popAddress;
}
},
watch: {
address_change() {
this.querySearchAsync();
this.searchTitle = this.formData.popAddress;
var that = this;
that.$nextTick(that.searchMap(window.BMap));
},
showDialog() {
if (this.showDialog) {
this.showPopup = this.showDialog;
}
}
},
mounted() {
var that = this;
that.$nextTick(that.createMap(window.BMap));
},
methods: {
createMap(BMap) {
// 百度地图API功能
let map = new BMap.Map(this.mapId || "map"); // 创建Map实例
map.centerAndZoom(new BMap.Point(113.668868, 34.750949), 12); // 初始化地图,设置中心点坐标和地图级别
//添加地图类型控件
map.setCurrentCity("郑州"); // 设置地图显示的城市 此项是必须设置的
map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放
},
searchMap(BMap) {
// 百度地图API功能
var map = new BMap.Map(this.mapId || "map");
map.centerAndZoom(new BMap.Point(113.668868, 34.750949), 12);
var local = new BMap.LocalSearch(map, {
renderOptions: { map: map }
});
local.search(this.searchTitle);
},
querySearchAsync() {
let obj = {
query: this.formData.popAddress,
region: "郑州",
output: "json",
ak: "NnbxvMwk23WZyuSk20mnAQ6SdK53Blcy"
};
this.$jsonp("http://api.map.baidu.com/place/v2/search", obj)
.then(response => {
let res = response.results.filter(item => item.detail);
this.list = res;
})
.catch(() => {});
},
handleSelect(item) {
this.formData.popAddress = item.address; //记录详细地址
this.formData.poplocation = item.location; //记录详细地址
this.$emit("delChange", this.formData);
},
enter(val) {
this.activeIndex = val;
this.searchTitle = this.list[val].name;
this.$nextTick(this.searchMap(window.BMap));
},
leave() {
this.activeIndex = -1;
},
selectChange(item) {
this.formData.popAddress = item.address;
this.formData.poplocation = item.location;
this.showPopup = false;
this.$emit("PopChange", this.formData);
},
close() {
this.showPopup = false;
}
}
};
</script>
<style lang="less" scoped>
.popup {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(0, 0, 0, 0.5);
z-index: 20;
.content {
width: 70%;
height: 70%;
background-color: #fff;
position: relative;
z-index: 2;
.map {
width: 99%;
height: 98%;
margin: 0.5%;
box-sizing: border-box;
z-index: 2;
}
.input-auto {
position: absolute;
top: 20px;
left: 20px;
display: flex;
align-items: flex-start;
z-index: 2;
.label {
font-size: 14px;
color: #333;
height: 40px;
padding: 0 15px;
box-sizing: border-box;
background-color: #fff6f1;
display: flex;
align-items: center;
justify-content: center;
}
.input-right {
.input {
width: 250px;
height: 40px;
border: none;
outline: none;
padding-left: 20px;
}
.menu {
width: 270px;
max-height: 300px;
// overflow: hidden;
overflow-y: auto;
display: flex;
border-top: solid #ddd 1px;
flex-direction: column;
background-color: #fff;
// padding: 5px 0;
.menu-item {
display: flex;
// flex-direction: column;
padding: 5px 10px;
align-items: center;
position: relative;
cursor: pointer;
.icon {
// width: 10px;
// height: 10px;
padding-right: 10px;
}
.text {
display: flex;
flex-direction: column;
.name {
width: 200px;
font-size: 13px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.addr {
width: 200px;
font-size: 12px;
color: #b4b4b4;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
}
}
:hover {
background-color: gainsboro;
}
.select {
position: absolute;
top: 50%;
right: 5px;
width: 30px;
height: 20px;
border-radius: 1px;
transform: translateY(-50%);
background-color: coral;
color: #fff;
font-size: 12px;
display: flex;
align-items: center;
justify-content: center;
}
}
}
.autocomplete {
width: 200px;
height: 40px;
border-top-left-radius: 0% !important;
}
}
.close {
position: absolute;
top: 0px;
right: 15px;
width: 30px;
height: 30px;
background-color: coral;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
}
}
</style>
2.使用
<Popup
:showDialog="showDialog"
:title="title"
:placeholder="placeholder"
:mapId="mapId"
@PopChange="PopChange"
></Popup>
import Popup from "../components/Popup";