添加地点搜索
parent
a39c2a8e6d
commit
0fb01cd478
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
Loading…
Reference in New Issue