最近接到一个新需要,要求如下:
当我点击选择地址时,弹出百度地图,
效果如下图:
实现方法:
1、首先要在百度地图开放平台去申请一个账号和key
2、申请好之后,在项目的index.html中引入
3、我写了一个组件,方便项目中任何地方可以调用:
这里一定要设置一个宽高,容器才能更好的适应,不然显示出来达不到想要的效果,如果没有设置高度还可能显示不出来
4、接下来就是开始初始化地图设置了,我的是在弹窗里面用,所有我写在watch里面的,当监测到弹窗打开时即开始初始化地图页面
5、具体方法如下:
直接附上源码:
<template lang="html">
<el-dialog v-dialogDrag title="选择地点" append-to-body width="800px" :visible.sync="mvisible" :close-on-click-modal="false"
@close="cancel"
>
<div id="amap-container">
<el-row>
<el-col :span="14">
<formatForm ref="basicInfoForm" class="basicForm" :form-list="basicInfoList" :form-validate="basicFormValidate" />
</el-col>
<el-col :span="10">
<el-input
id="search-input"
v-model="searchValue"
class="input-with"
placeholder="请输入详细地址"
clearable
@clear="handelclearInput"
@keyup.native.enter="onhandelSearch"
>
<el-button
slot="append"
size="small"
type="primary"
icon="el-icon-search"
@click="onhandelSearch"
>搜索
</el-button>
</el-input>
</el-col>
</el-row>
<el-row class="margin-top-10 address">
当前地址是: {{ addressName }}{{ searchValue }}
</el-row>
<div id="mapBox" />
</div>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="handelSave">保 存</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
</template>
<script>
import { cleanChildrenEmpty } from '@/utils/filterArrayData'
import { getAddressName } from '@/utils/getAddressName'
import { selectRequired } from '@/utils/formRules'
// import AMapLoader from '@amap/amap-jsapi-loader'
import region from '@/static/json/region.json'
import formatForm from '@/components/formatForm/index'
// import { BMap } from 'vue-baidu-map/types'
// const BMapGL = require('vue-baidu-map/types/map')
let BMapGL = {}
let map = {}
const addressOption = cleanChildrenEmpty(region, 'children')
export default {
name: 'AMap',
components: { formatForm },
props: {
businessProvinceId: {
type: Array,
default: () => []
},
defaultValue: {
type: String,
default: ''
},
visible: {
type: Boolean,
default: false
}
},
data() {
const that = this
return {
mvisible: false,
defaultCity: '',
// 地址对应的经纬度信息
lat: '',
lng: '',
// 检索关键字
searchValue: '',
// 地址名称
adcode: '',
basicInfoList: {
span: 24,
title: '',
labelWidth: '70px',
isColon: true,
list: [
{
type: 'cascader',
exist: true,
fieldName: '省市区',
fieldEName: 'businessProvinceId',
expandTrigger: 'hover',
label: 'name',
value: 'id',
placeholder: '请选择省市区',
options: addressOption,
rules: [selectRequired],
change: res => {
this.addressName = res.length ? getAddressName(res, addressOption).name : ''
this.onhandelSearch()
}
}
]
},
basicFormValidate: {
businessProvinceId: []
},
addressName: '',
district: '',
newDistrict: ''
}
},
watch: {
defaultValue() {
this.searchValue = this.defaultValue
},
visible() {
this.mvisible = this.visible
this.searchValue = this.defaultValue
console.log(this.businessProvinceId.length, this.defaultValue)
this.basicFormValidate.businessProvinceId = this.businessProvinceId || []
this.addressName = this.businessProvinceId.length && !this.defaultValue ? getAddressName(this.businessProvinceId, addressOption).name : ''
const oldDistrict = this.businessProvinceId.length && !this.defaultValue ? (getAddressName(this.businessProvinceId, addressOption).name2).split('-') : []
this.district = oldDistrict.length ? oldDistrict[oldDistrict.length - 1] : ''
this.$nextTick(() => {
// 初始化地图页面
this.initMap()
})
}
},
beforeDestroy() {
// 销毁地图
// this.map.destroy()
},
methods: {
initMap() {
BMapGL = window.BMapGL
map = new BMapGL.Map('mapBox') // 创建Map实例
map.centerAndZoom(new BMapGL.Point(116.404, 39.915), 12) // 初始化地图,设置中心点坐标和地图级别
map.enableScrollWheelZoom(true) // 开启鼠标滚轮缩放
console.log('this.addressName', this.addressName)
const center = this.addressName
map.setCenter(center)
this.getPoint()
this.getClickMapIp()
// // 添加maker
// this.setMaker()
// // 添加鼠标点选地图选择地址
// this.addAmapGeocoder()
// this.onhandelSearch()
},
getPoint() {
const center = this.addressName || this.searchValue
const myGeo = new BMapGL.Geocoder()
myGeo.getPoint(center, (point) => {
if (point) {
map.centerAndZoom(point, 12)
map.addOverlay(new BMapGL.Marker(point, { title: center }))
} else {
alert('您选择的地址没有解析到结果!')
}
}, this.addressName)
},
getClickMapIp() {
map.addEventListener('click', (e) => {
console.log('e----', e)
this.lat = e.latlng.lat
this.lng = e.latlng.lng
const point = new BMapGL.Point(this.lng, this.lat)
map.centerAndZoom(point, 12) // 初始化地图,设置中心点坐标和地图级别
this.setMarker(point)
// 指定经纬度获取地址
this.getLocation(point)
})
},
// 添加marker
setMarker(new_point) {
map.clearOverlays()
const marker = new BMapGL.Marker(new_point)
map.addOverlay(marker) // 将标注添加到地图中
map.panTo(new_point)
},
// 获取地址
getLocation(pt) {
// 创建地理编码实例
const myGeo = new BMapGL.Geocoder()
console.log('myGeo', myGeo)
myGeo.getLocation(pt, (re) => {
const { province, city, district, street, streetNumber } = re.addressComponents || {}
this.newDistrict = district
this.addressName = `${province || ''}${city || ''}${district || ''}`
this.searchValue = `${street || ''}${streetNumber || ''}`
console.log('getLocation', re)
// this.getCityCode(district)
})
},
getCityCode(city) {
console.log('city', city)
const myCity = new BMapGL.Geolocation()
console.log('myCity', myCity)
myCity.getCityCode(city, res => {
console.log('getCurrentPosition======', res)
})
},
// 按钮触发检索
onhandelSearch() {
const local = new BMapGL.LocalSearch(map, {
renderOptions: { map: map }
})
const address = this.addressName + this.searchValue
local.search(address)
},
handelclearInput() {
this.searchValue = ''
},
// 保存当前选择的地址,分发事件
handelSave() {
const { newDistrict, district, lat, lng } = this
const { businessProvinceId } = this.basicFormValidate
console.log('businessProvinceId', businessProvinceId)
const s = district ? district === newDistrict : true
if (businessProvinceId.length === 3 && lat && lng && s) {
const x_pi = 3.14159265358979324 * 3000.0 / 180.0
const x = lng - 0.0065
const y = lat - 0.006
const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi)
const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi)
const lngs = z * Math.cos(theta)
const lats = z * Math.sin(theta)
const data = {
name: this.name,
businessProvinceId,
// 地址名称
address: this.formattedAddress,
// 纬度lat
lat: lats,
// 经度lng
lng: lngs
}
this.$emit('getPosition', true, data)
} else {
this.$message.error('当前地址不在省市区范围内,请重新选择')
}
},
cancel() {
this.$emit('getPosition', false)
}
}
}
</script>
<style scoped lang="scss">
#amap-container {
margin: 20px;
.el-input__clear {
line-height: 34px;
/*top: 20px;*/
}
#mapBox {
height: 35vh;
width: 100%;
margin-top: 10px;
border: 1px solid #ccc;
}
.input-with {
/*position: fixed;*/
/*top: 40px;*/
z-index: 1;
width: 580px;
}
.address {
color: #373737;
}
}
.amap-sug-result {
z-index: 99999;
}
.baseForm.format_form {
margin: 0 !important;
}
</style>
根据项目需求做调整即可。
好了就这样吧,助人达已,爱分享爱学习,做一个快乐的前端小姐姐
如有更好的方法,欢迎交流!!