首先安装地图插件
cnpm i @amap/amap-jsapi-loader --save
封装地图子组件
< template>
< el- dialog
title= "选择地点"
width= "740px"
class = "select-map-dialog"
v- model= "dialogShow"
: close- on- click- modal= "false"
: modal- orgend- to- body= "false"
: append- to- body= "true"
@close= "cancel"
>
< div class = "amap-box" >
< el- input clearable id= "keyword" v- model= "tipInput" placeholder= "关键词搜索" : prefix- icon= "Search" > < / el- input>
< div id= "custom-amap" > < / div>
< div class = "info-list" v- if = "address" >
< div class = "info-item" > 已选择地点:{ { address } } < / div>
< div class = "info-item" > 地点经纬度:{ { point } } < / div>
< / div>
< / div>
< template #footer>
< div class = "dialog-footer" >
< el- button type= "primary" @click= "handelSave" > 确定< / el- button>
< el- button @click= "cancel" > 取消< / el- button>
< / div>
< / template>
< / el- dialog>
< / template>
< script setup>
import { ref, onUnmounted, watch, computed, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import AMapLoader from '@amap/amap-jsapi-loader'
import { Search } from '@element-plus/icons-vue'
const map = ref ( null )
const address = ref ( '' )
const point = ref ( [ ] )
const marker = ref ( '' )
const geocoder = ref ( '' )
const tipInput = ref ( '' )
const autoComplete = ref ( null )
const placeSearch = ref ( null )
const props = defineProps ( {
defaultAddress: {
type: String,
default : ''
} ,
defaultPoint: {
type: Array,
default : [ ]
} ,
isShow: {
type: Boolean,
default : false
}
} )
const emits = defineEmits ( [ 'update:isShow' , 'getPosition' ] )
const dialogShow = computed ( {
get : ( ) => props. isShow,
set : ( value ) => {
emits ( 'update:isShow' , value)
}
} )
watch (
( ) => dialogShow,
async ( ) => {
setTimeout ( ( ) => {
initMap ( )
} , 100 )
} ,
{ deep: true } ,
{ immediate: true }
)
const initMap = ( ) => {
AMapLoader. load ( {
key: '你的key' ,
version: '2.0' ,
plugins: [
'AMap.ToolBar' ,
'AMap.Scale' ,
'AMap.HawkEye' ,
'AMap.MapType' ,
'AMap.Geolocation' ,
'AMap.AutoComplete' ,
'AMap.PlaceSearch' ,
'AMap.Geocoder'
]
} )
. then ( ( AMap ) => {
const tempCenter = props. defaultPoint[ 0 ]
? props. defaultPoint
: [ 118.784136 , 32.041806 ]
map. value = new AMap. Map ( 'custom-amap' , {
viewMode: '2D' ,
zoom: 12 ,
showLabel: true ,
resizeEnable: true ,
center: tempCenter
} )
if ( props. defaultPoint. length > 0 ) {
address. value = props. defaultAddress
point. value = props. defaultPoint
addMarker ( )
}
map. value. on ( 'click' , clickMapHandler)
map. value. addControl ( new AMap. Scale ( ) )
map. value. addControl ( new AMap. ToolBar ( ) )
map. value. addControl ( new AMap. HawkEye ( ) )
map. value. addControl ( new AMap. MapType ( ) )
map. value. addControl ( new AMap. Geolocation ( ) )
autoComplete. value = new AMap. AutoComplete ( {
input: 'keyword'
} )
placeSearch. value = new AMap. PlaceSearch ( {
map: map. value
} )
autoComplete. value. on ( 'select' , selectHandler)
placeSearch. value. on ( 'markerClick' , clickMarkerHandler)
} )
. catch ( ( e ) => {
console. log ( e)
} )
}
const clickMapHandler = ( e ) => {
const lng = e. lnglat. lng
const lat = e. lnglat. lat
point. value = [ lng, lat]
addMarker ( )
getAddress ( )
}
const addMarker = ( ) => {
if ( marker. value) {
marker. value. setMap ( null )
marker. value = null
}
marker. value = new AMap. Marker ( {
position: point. value,
offset: new AMap. Pixel ( - 13 , - 30 ) ,
icon: new AMap. Icon ( {
image:
'//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png' ,
size: new AMap. Size ( 30 , 40 ) ,
imageSize: new AMap. Size ( 30 , 40 )
} )
} )
marker. value. setMap ( map. value)
}
const getAddress = ( ) => {
geocoder. value = new AMap. Geocoder ( )
geocoder. value. getAddress ( point. value, ( status, result ) => {
if ( status === 'complete' && result. info === 'OK' ) {
if ( result && result. regeocode) {
address. value = result. regeocode. formattedAddress
}
}
} )
}
const selectHandler = ( e ) => {
placeSearch. value. setCity ( e. poi. adcode)
placeSearch. value. search ( e. poi. name)
}
const clickMarkerHandler = ( e ) => {
point. value = [ e. data. location. lng, e. data. location. lat]
getAddress ( )
}
const handelSave = ( ) => {
if ( address. value && point. value. length && point. value. length > 0 ) {
const infoObj = {
address: address. value,
point: point. value
}
tipInput. value = ''
emits ( 'getPosition' , infoObj)
} else {
ElMessage. error ( '请选择地址获取经纬度' )
}
}
const cancel = ( ) => {
tipInput. value = ''
}
onUnmounted ( ( ) => {
map. value && map. value. destroy ( )
} )
< / script>
< style lang= "scss" scoped>
. amap- box {
padding: 5 px 0 0 ;
#custom- amap {
width: 700 px;
height: 400 px;
margin- top: 10 px;
border: 1 px solid #ccc;
}
. input- with {
width: 580 px;
z- index: 1 ;
}
. address {
color: #373737 ;
}
. info- list {
padding: 5 px 5 px 0 ;
line- height: 24 px;
}
}
< / style>
< style lang= "scss" >
. select- map- dialog {
. el- dialog__body {
padding- top: 3 px;
padding- bottom: 3 px;
}
}
. amap- sug- result {
z- index: 2024 ;
}
< / style>
父组件引用子组件
< amap : isShow= "amapVisible" @getPosition= "getPosition" / >
const getPosition = ( infoObj ) => {
amapVisible. value = false
}