一、utils目录下新建utils.ts
/** 加载腾讯地图 */
//txMapKey为腾讯地图申请的mapKey
const txMapKey = 'DZVBZ-J27A6-E4TSU-MZXE4-TUYXH-W5BJI'
let txMapInstance = null
export const loadTxMapPromise: () => Promise<Recordable> = () => {
return new Promise((resolve, reject) => {
if (txMapInstance) return resolve(txMapInstance)
const script = document.createElement('script')
script.type = 'text/javascript'
script.src = `https://map.qq.com/api/gljs?v=1.exp&libraries=service&key=${txMapKey}`
script.onload = function () {
console.log('腾讯地图加载成功')
// @ts-ignore
txMapInstance = window.TMap
resolve(txMapInstance)
}
script.onerror = function () {
console.log('腾讯地图加载失败')
reject()
}
document.body.appendChild(script)
})
}
一、新建腾讯地图组件 TencentMaps.vue
<template>
<div>
<div id="panel">
<el-form-item label="" prop="companyName">
<div class="flex items-center">
<el-input
placeholder="请输入关键词"
clearable
id="keyword"
type="text"
v-model="searchForm.keyword"
@input="getSuggestions()"
/>
<el-button id="search" class="ml-[10px]" type="primary" @click="searchByKeyword()">
搜索
</el-button>
</div>
</el-form-item>
<ul id="suggestionList" />
</div>
<div id="container" />
</div>
</template>
<script setup lang="ts">
import { onMounted, reactive } from 'vue'
import { loadTxMapPromise } from '/@/utils/utils'
defineOptions({
name: 'TencentMaps',
})
// 获取父组件传值
const pro = defineProps({
modelValue: Object,
})
const emit = defineEmits(['update:modelValue', 'active-change'])
const onActiveChange = (value: Recordable) => {
console.log('value', value)
emit('active-change', value)
}
const searchForm = reactive({
keyword: undefined,
})
let map = undefined
let suggestionList = undefined
let search = undefined
let suggest = undefined
let markers = undefined
let infoWindowList = []
let TMap = undefined
let infoWindow = undefined
onMounted(async () => {
init()
// vue3+ts使用原生click事件报错
// 搭建桥梁=>在setup中添加=>window.setSuggestion= setSuggestion;
window.setSuggestion = setSuggestion
})
//初始化地图
const init = async () => {
// console.log('modelValue', pro.modelValue)
TMap = await loadTxMapPromise()
console.log('TMap', TMap)
map = new TMap.Map('container', {
zoom: 14,
center: new TMap.LatLng(pro.modelValue.lat, pro.modelValue.lng),
})
suggestionList = []
search = new TMap.service.Search({ pageSize: 10 }) // 新建一个地点搜索类
suggest = new TMap.service.Suggestion({
// 新建一个关键字输入提示类
pageSize: 10, // 返回结果每页条目数
region: pro.modelValue.cityStr || '', // 限制城市范围
regionFix: true, // 搜索无结果时是否固定在当前城市
})
markers = new TMap.MultiMarker({
map: map,
geometries: [],
})
infoWindowList = Array(10)
}
const getSuggestions = () => {
// 使用者在搜索框中输入文字时触发
let suggestionListContainer = document.getElementById('suggestionList')
suggestionListContainer.innerHTML = ''
let keyword = searchForm.keyword
// console.log('keyword', keyword)
if (keyword) {
suggest
.getSuggestions({ keyword: keyword, location: map.getCenter() })
.then((result) => {
// console.log('result.data', result.data)
// 以当前所输入关键字获取输入提示
suggestionListContainer.innerHTML = ''
suggestionList = result.data
suggestionList.forEach((item, index) => {
suggestionListContainer.innerHTML += `<li onclick="setSuggestion(${index})">${item.title}<span class="item_info">${item.address}</span></li>`
// suggestionListContainer.innerHTML += `<li><a href="#/merchant/auditingList" onclick="setSuggestion(${index})">${item.title}<span class="item_info">${item.address}</span></a></li>`
})
})
.catch((error) => {
console.log(error)
})
}
}
const setSuggestion = function (index: number) {
// console.log('index', index)
if (infoWindowList && infoWindowList.length == 0)
// 点击输入提示后,于地图中用点标记绘制该地点,并显示信息窗体,包含其名称、地址等信息
infoWindowList.forEach((infoWindow) => {
infoWindow.close()
})
infoWindowList.length = 0
searchForm.keyword = suggestionList[index].title
document.getElementById('suggestionList').innerHTML = ''
markers.setGeometries([])
markers.updateGeometries([
{
id: '0', // 点标注数据数组
position: suggestionList[index].location,
},
])
// console.log('markers', markers)
infoWindow = new TMap.InfoWindow({
map: map,
position: suggestionList[index].location,
content: `<h3>${suggestionList[index].title}</h3><p>地址:${suggestionList[index].address}</p>`,
offset: { x: 0, y: -50 },
})
infoWindowList.push(infoWindow)
map.setCenter(suggestionList[index].location)
markers.on('click', (e) => {
infoWindowList[Number(e.geometry.id)].open()
// console.log('infoWindowList[Number(e.geometry.id)]', infoWindowList[Number(e.geometry.id)])
// 选择经纬度
onActiveChange(infoWindowList[Number(e.geometry.id)].position)
})
}
const searchByKeyword = () => {
// 关键字搜索功能
infoWindowList.forEach((infoWindow) => {
infoWindow.close()
})
infoWindowList.length = 0
markers.setGeometries([])
search
.searchRectangle({
keyword: searchForm.keyword,
bounds: map.getBounds(),
})
.then((result) => {
// console.log('result.data1', result.data)
result.data.forEach((item, index) => {
let geometries = markers.getGeometries()
infoWindow = new TMap.InfoWindow({
map: map,
position: item.location,
content: `
<h3>${item.title}</h3>
<p>地址:${item.address}</p>
<p>电话:${item.tel}</p>
`,
offset: { x: 0, y: -50 },
})
infoWindow.close()
infoWindowList[index] = infoWindow
geometries.push({
id: String(index),
position: item.location,
})
markers.updateGeometries(geometries)
markers.on('click', (e) => {
// console.log(
// 'infoWindowList[Number(e.geometry.id)]',
// infoWindowList[Number(e.geometry.id)]
// )
infoWindowList[Number(e.geometry.id)].open()
// 选择经纬度
onActiveChange(infoWindowList[Number(e.geometry.id)].position)
})
})
})
}
</script>
<style lang="scss" scoped>
// 腾讯地图
#container {
width: 100%;
height: 100%;
}
#panel {
position: absolute;
background: #fff;
width: 350px;
padding: 20px;
z-index: 9999;
top: 30px;
left: 30px;
}
#suggestionList {
list-style-type: none;
padding: 0;
margin: 0;
}
#suggestionList li a {
margin-top: -1px;
background-color: #f6f6f6;
text-decoration: none;
font-size: 18px;
color: black;
display: block;
}
#suggestionList li .item_info {
font-size: 12px;
color: grey;
}
#suggestionList li a:hover:not(.header) {
background-color: #eee;
}
</style>
三、页面引用
<template>
<TencentMaps :modelValue="modelValue" @active-change="setLngLat" />
</emplate>
<script setup lang="ts">
const modelValue = ref({
lng: undefined,
lat: undefined,
cityStr: undefined,
})
//获取腾讯地图组件传值
const setLngLat = (value: Recordable) => {
console.log('value', value)
}
</sript>
四、知识点
1、ue3+ts使用原生click事件报错
解决: 搭建桥梁=>在setup中添加=>window.setSuggestion= setSuggestion
2、参考:腾讯地图