添加地点搜索

pull/853/head
wersd 2025-06-26 21:23:04 +08:00
parent a39c2a8e6d
commit 0fb01cd478
2 changed files with 117 additions and 15 deletions

View File

@ -1,12 +1,29 @@
<template>
<!-- 地图容器 -->
<div id="map-container" ref="mapContainer"></div>
<div id="map-container" ref="mapContainer">
<div id="panel">
<el-input
id="keyword"
v-model="keyword"
placeholder="请输入关键字"
@input="getSuggestions"
style="width: 180px; margin-right: 8px; font-size: 16px;"
clearable
/>
<ul id="suggestionList" v-if="suggestionList.length">
<li v-for="(item, index) in suggestionList" :key="item.id">
<a href="#" @click.prevent="setSuggestion(index)">
{{ item.title }}<span class="item_info">{{ item.address }}</span>
</a>
</li>
</ul>
</div>
<div id="tmap-inner" ref="tmapInner"></div>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue'
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'
// props
const props = defineProps({
center: {
type: Object,
@ -22,35 +39,44 @@ const props = defineProps({
}
})
//
const map = ref(null)
const mapContainer = ref(null)
const emit = defineEmits(['map-click'])
const tmapInner = ref(null)
const emit = defineEmits(['map-click', 'suggestion-select'])
let markerLayer = null
let suggest = null
const suggestionList = ref([])
const keyword = ref('')
const API_KEY = import.meta.env.VITE_APP_TENCENT_MAP_KEY
onMounted(() => {
const script = document.createElement('script')
script.src = `https://map.qq.com/api/gljs?v=1.exp&key=${API_KEY}`
script.onload = initMap
script.src = `https://map.qq.com/api/gljs?v=1.exp&libraries=service&key=${API_KEY}`
script.onload = () => nextTick(initMap)
document.head.appendChild(script)
})
function initMap() {
if (!window.TMap) {
if (!window.TMap) {
console.error('腾讯地图API加载失败')
return
}
map.value = new TMap.Map(mapContainer.value, {
map.value = new TMap.Map(tmapInner.value, {
center: new TMap.LatLng(props.center.lat, props.center.lng),
zoom: props.zoom,
viewMode: '2D'
})
map.value.on('click', (evt) => {
//
emit('map-click', evt)
})
markerLayer = new TMap.MultiMarker({
map: map.value,
geometries: []
})
suggest = new TMap.service.Suggestion({
pageSize: 10,
region: '杭州',
regionFix: false
})
if (props.markers && props.markers.length > 0) {
addMarkers()
}
@ -62,7 +88,7 @@ function addMarkers() {
markerLayer = new TMap.MultiMarker({
map: map.value,
styles: {
"marker": new TMap.MarkerStyle({
marker: new TMap.MarkerStyle({
width: 25,
height: 35,
anchor: { x: 12.5, y: 35 }
@ -83,8 +109,38 @@ function removeMarker() {
}
}
function getSuggestions() {
suggestionList.value = []
if (!suggest || !keyword.value) return
suggest.getSuggestions({ keyword: keyword.value, location: map.value.getCenter() })
.then((result) => {
suggestionList.value = result.data
})
.catch(() => {})
}
function setSuggestion(index) {
const selected = suggestionList.value[index]
if (!selected) return
keyword.value = selected.title
suggestionList.value = []
const position = selected.location
map.value.setCenter(new TMap.LatLng(position.lat, position.lng))
markerLayer.setGeometries([
{
position: new TMap.LatLng(position.lat, position.lng),
id: selected.id,
styleId: 'marker'
}
])
// emit
emit('suggestion-select', {
lat: position.lat,
lng: position.lng,
name: selected.title + (selected.address ? ' ' + selected.address : '')
})
}
// props
watch(() => props.center, (val) => {
if (map.value && val) {
map.value.setCenter(new TMap.LatLng(val.lat, val.lng))
@ -112,5 +168,43 @@ onUnmounted(() => {
#map-container {
width: 100%;
height: 100%;
position: relative;
}
#tmap-inner {
width: 100%;
height: 100%;
}
#panel {
position: absolute;
top: 10px;
left: 10px;
z-index: 9999;
}
#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;
margin-left: 8px;
}
#suggestionList li a:hover:not(.header) {
background-color: #eee;
}
#keyword {
width: 180px;
margin-right: 8px;
padding: 4px 8px;
font-size: 16px;
}
</style>

View File

@ -89,6 +89,7 @@
:zoom="16"
:markers="tempLocation.lat && tempLocation.lng ? [{ id: 'selected', content: formData, position: { lat: tempLocation.lat, lng: tempLocation.lng } }] : []"
@map-click="handleMapClick"
@suggestion-select="handleSuggestionSelect"
/>
<div style="margin-top: 10px; text-align: right;">
<el-button @click="mapDialogVisible = false">取消</el-button>
@ -536,4 +537,11 @@ const confirmManagementSelection = () => {
}
managementDialogVisible.value = false
}
function handleSuggestionSelect({ lat, lng, name }) {
formData.value.locationLat = lat
formData.value.locationLng = lng
formData.value.locationName = name
tempLocation.value = { lat, lng }
}
</script>