一、参考资料
高德开放平台 | 高德地图API (amap.com)
二、安装及配置
pnpm i @vuemap/vue-amap --save
man.ts 密钥及安全密钥需要自己到高德地图开放平台控制台获取.
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import vant from 'vant'
import 'vant/lib/index.css'
import VueAMap, { initAMapApiLoader } from '@vuemap/vue-amap'
import '@vuemap/vue-amap/dist/style.css'
import * as echarts from 'echarts'
initAMapApiLoader({
key: '841d5250cb7f61adda2ee70c1e3abdaf',
securityJsCode: 'd122cbf5a33de34356661cf0cef1a553', // 新版key需要配合安全密钥使用
plugins: [
// 定位空间,用来获取和展示用户主机所在的经纬度位置
'AMap.Geolocation',
// 输入提示插件
'AMap.Autocomplete',
// POI搜索插件
'AMap.PlaceSearch',
// 右下角缩略图插件,比例尺
'AMap.Scale',
// 地图鹰眼插件
'AMap.OverView',
// 地图工具条
'AMap.ToolBar',
// 类别切换空间,实现默认图层与卫星图,实施交通层之间切换的控制
'AMap.MapType',
// 编辑 折线多边形
'AMap.PolyEditor',
'AMap.CircleEditor',
// 地图编码
'AMap.Geocoder'
]
})
const app = createApp(App)
//全局挂载echarts
app.config.globalProperties.$echarts = echarts
app.use(router)
app.use(ElementPlus)
app.use(VueAMap)
app.use(vant)
app.mount('#app')
三、源码分享
1、map.vue
<template>
<el-dialog v-model="showMapDialog">
<template #default>
<div id="container">
<AmapSelect v-model="locationData" @callback="getMapInfo" />
</div>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { ref, nextTick, defineEmits } from 'vue'
// import { ElMessage } from 'element-plus';
import AmapSelect from './AmapSelect.vue'
const props = defineProps({
title: {
type: String,
default: '选择位置'
},
center: {
type: Array,
default: () => [115.846381, 28.659961]
}
})
const locationData:any = ref([])
const showMapDialog = ref(false)
const emit = defineEmits(['submit'])
function getMapInfo(info: any) {
// console.log(info,'info'); 可拿到点击的地址 以及经纬度 可用于做回显等其他操作
// debugger
emit('submit', {
address: info.address,
lnglat: info.lnglat
})
}
const openForm = () => {
showMapDialog.value = true
nextTick(() => {
locationData.value=props.center;
})
}
//提交
// const okModal = async () => {}
//导出方法
defineExpose({
openForm
})
</script>
<style lang="scss" scoped>
#container {
height: 400px;
}
.el-dialog__body {
padding: 0 !important;
}
</style>
2、AmapSelect.vue
<template>
<el-amap :zoom="zoom" @init="init">
<el-amap-search-box
:visible="visible"
@select="selectChange"
@choose="handleChange"
placeholder="请输入"
/>
</el-amap>
</template>
<script>
export default {
name: 'AmapSelect',
emits: ['callback'],
props: {
visible: {
type: Boolean,
default: true
},
modelValue: {
type: Array,
default: []
}
},
data() {
return {
zoom: 12,
map: null,
geocoder: new AMap.Geocoder({}),
activeAddress: null,
}
},
watch: {
modelValue: {
handler(val, oldVal) {
if (val) {
// let lnglat = val[1].split(',')
this.onClickMap({
lnglat: { lng: val[0], lat: val[1] }
})
}
},
deep: true
}
},
mounted() {},
methods: {
init(map) {
this.map = map
map.on('click', this.onClickMap.bind(this))
},
selectChange({ poi }) {
if (poi.location) {
let { lng, lat } = poi.location
this.onClickMap(
{
lnglat: { lng, lat }
},
() => {
this.map.setCenter([lng, lat])
}
)
}
},
handleChange(e) {
console.log('handleChange: ', e)
},
// 点击地图
onClickMap(e, callback) {
let lnglat = [e.lnglat.lng, e.lnglat.lat]
var infoWindow = new AMap.InfoWindow({
offset: new AMap.Pixel(0, 0)
})
this.geocoder.getAddress(lnglat, (status, result) => {
if (status === 'complete' && result.info === 'OK') {
// result为对应的地理位置详细信息
var province = result.regeocode.addressComponent.province //省
var city = result.regeocode.addressComponent.city //市
var district = result.regeocode.addressComponent.district //县区
var township = result.regeocode.addressComponent.township //镇、街道
var region = province + city + district + township //返回所属区域
let addressName = result.regeocode.formattedAddress.replace(
region,
''
)
let address = ''
if (!addressName) {
address = region
addressName = region
} else {
address = result.regeocode.formattedAddress
}
let obj = {
lnglat: lnglat.toString(),
address: address,
addressName: addressName
}
infoWindow.setContent(this.createdInfoWindowContent(obj))
infoWindow.open(this.map, lnglat) // 更新数据
callback && callback()
}
})
this.map.setCenter(lnglat)
},
// 窗口信息
createdInfoWindowContent(data) {
var infoWindowContent =
'<style>.btn {display: inline-block; font-weight: 400; text-align: center; white-space: nowrap; vertical-align: middle;' +
'-webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; border: 1px solid transparent;' +
'transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out;' +
'background-color: transparent; background-image: none; color: #25A5F7; border-color: #25A5F7; padding: .25rem .5rem; line-height: 1.5;' +
'border-radius: 1rem; -webkit-appearance: button; cursor:pointer;}</style>' +
'<div className="custom-infowindow input-card">' +
'<label class="input-item-text">' +
data.addressName +
'</label>' +
'<div class="input-item">' +
'<div class="input-item-prepend">' +
'<span style="color:grey">' +
data.address +
'</span>' +
'</div>' +
'</div>' + // 为 infowindow 添加自定义事件
'<input id="lnglat2container" type="button" class="btn" value="选择地址" onclick="setLngLat()"/>' +
'</div>'
// debugger;
window.setLngLat = () => {
this.$emit('update:modelValue', [data.address, data.lnglat])
this.$emit('callback', data)
}
return infoWindowContent
}
}
}
</script>
<style lang="scss" scoped>
</style>
四、效果展示
点击窗口信息的选择地址可拿到点击位置的信息然后再做后续操作!!!主要还是参考高德地图API的官方文档.