复制代码
<template>
<div>
<div id="container" ref="mapContainer"></div>
</div>
</template>
<script setup lang="ts">
import { ref, defineExpose } from 'vue'
import { loadTMap } from './index' // 你封装的腾讯地图加载器
import { ElMessage } from 'element-plus'
// 类型定义
interface Position {
lat: number
lng: number
}
interface GeocoderResultDetail {
location: Position, //经纬度
address: string ,//详细地址
[key: string]: any //省市区
}
// Props
const props = withDefaults(defineProps<{
lat?: number
lon?: number
mapKey: string,
region?:string //城市
}>(), {
lat: 30.570676,
lon: 104.065173,
region:"成都市"
})
// Emits
const emit = defineEmits<{
(e: 'getCoordinates', detail: GeocoderResultDetail): void
}>()
const mapContainer = ref<HTMLElement | null>(null)
const mapInstance = ref<any>(null)
const geocoder = ref<any>(null)
const marker = ref<any>(null)
const resultDetail = ref<GeocoderResultDetail | null>(null)
const hasLoaded = ref(false)
const TMap=ref()
// 初始化地图
const initMap = async () => {
if (hasLoaded.value) return
try {
if (!props.mapKey) return console.warn('地图Key为空')
await loadTMap(props.mapKey)
const TMap = window.TMap
if (!TMap || !mapContainer.value) throw new Error('TMap 加载失败')
const center = new TMap.LatLng(props.lat, props.lon)
mapInstance.value = new TMap.Map(mapContainer.value, {
center,
zoom: 15
})
// 初始化地理编码器
geocoder.value = new TMap.service.Geocoder()
// 初始点反查地址
geocoder.value.getAddress({ location: center })
// 点击地图获取坐标并反查地址
mapInstance.value.on('click', (e: any) => {
const latLng = new TMap.LatLng(e.latLng.lat, e.latLng.lng)
setMarker(latLng)
geocoder.value.getAddress({
location: latLng,
success: (res: { result: GeocoderResultDetail }) => {
resultDetail.value = res.result
console.log("哈哈哈", res.result)
// emit('getCoordinates', {
// location: latLng,
// })
},
fail: (err: any) => {
console.error('地址解析失败:', err)
}
})
})
hasLoaded.value = true
} catch (error) {
console.error('地图初始化失败:', error)
}
}
// 打点函数
const setMarker = (latLng: Position) => {
if (marker.value) marker.value.setMap(null)
const center = new window.TMap.LatLng(latLng.lat, latLng.lng)
const point = new window.TMap.LatLng(latLng.lat, latLng.lng)
// 设置地图中心点
mapInstance.value.setCenter(center)
try{
marker.value = new window.TMap.MultiMarker({
map: mapInstance.value,
styles: {
marker: new window.TMap.MarkerStyle({
width: 25,
height: 35,
anchor: { x: 16, y: 32 },
src: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/markerDefault.png'
})
},
geometries:[{
"id": "1",
"styleId": 'marker',
"position": point,
"properties": {
"title": "marker4"
}
}]
})
geocoder.value.getAddress({
location: point,
}).then((res:{result:GeocoderResultDetail })=>{
const {result}=res
emit('getCoordinates', {
type: 'getAddress',
location: {
lat:result.location.lat,
lng:result.location.lng
},
address: result.address,
addressInfo: {
province:result.ad_info.province,
city:result.ad_info.city,
district:result.ad_info.district
}
})
});
}catch(err){
console.log(err,"家家爱")
}
}
// 父组件传入地址,地图定位并打点
const setAddress = (address: string) => {
if (!geocoder.value || !mapInstance.value) return
geocoder.value.getLocation({
address: address,
}).then((res:{result:GeocoderResultDetail })=>{
const {result}=res
setMarker({
lat:result.location.lat,
lng: result.location.lng
})
emit('getCoordinates', {
type: 'getLocation',
location: {
lat:result.location.lat,
lng:result.location.lng
},
address: result.address,
addressInfo: {
province:result.ad_info.province,
city:result.ad_info.city,
district:result.ad_info.district
}
})
}).catch( (e:any) =>{
console.log(e)
ElMessage.error(e.message)
})
}
// 暴露方法给父组件
defineExpose({
initMap,
setAddress,
getMap: () => mapInstance.value
})
</script>
<style scoped>
#container {
width: 100%;
height: 450px;
}
</style>