xlqx/app/pages/map-demo.vue
2025-10-29 14:44:25 +08:00

373 lines
7.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="map-demo-page">
<div class="page-header">
<h1>高德地图组件演示</h1>
<p>基于您提供的HTML示例创建的Vue组件</p>
</div>
<div class="demo-section">
<h2>基础地图</h2>
<div class="map-controls">
<div class="control-group">
<label>中心点坐标</label>
<input
v-model="centerLng"
type="number"
step="0.000001"
placeholder="经度"
class="coord-input"
/>
<input
v-model="centerLat"
type="number"
step="0.000001"
placeholder="纬度"
class="coord-input"
/>
<button @click="updateCenter" class="update-btn">更新中心点</button>
</div>
<div class="control-group">
<label>缩放级别:</label>
<input
v-model.number="zoomLevel"
type="range"
min="3"
max="18"
class="zoom-slider"
/>
<span class="zoom-value">{{ zoomLevel }}</span>
</div>
<div class="control-group">
<label>视图模式:</label>
<select v-model="viewMode" class="view-select">
<option value="2D">2D模式</option>
<option value="3D">3D模式</option>
</select>
</div>
</div>
<AMapComponent
ref="mapRef"
:center="mapCenter"
:zoom="zoomLevel"
:view-mode="viewMode"
height="500px"
@map-ready="onMapReady"
@map-click="onMapClick"
@zoom-change="onZoomChange"
@center-change="onCenterChange"
/>
</div>
<div class="demo-section">
<h2>地图事件信息</h2>
<div class="event-info">
<div class="info-item">
<strong>地图状态:</strong>
<span :class="mapStatusClass">{{ mapStatus }}</span>
</div>
<div class="info-item" v-if="lastClick">
<strong>最后点击位置</strong>
<span>{{ lastClick.lng.toFixed(6) }}, {{ lastClick.lat.toFixed(6) }}</span>
</div>
<div class="info-item" v-if="currentCenter">
<strong>当前中心点</strong>
<span>{{ currentCenter.lng.toFixed(6) }}, {{ currentCenter.lat.toFixed(6) }}</span>
</div>
<div class="info-item">
<strong>当前缩放级别</strong>
<span>{{ currentZoom }}</span>
</div>
</div>
</div>
<div class="demo-section">
<h2>快速定位</h2>
<div class="quick-locations">
<button
v-for="location in quickLocations"
:key="location.name"
@click="goToLocation(location)"
class="location-btn"
>
{{ location.name }}
</button>
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
import AMapComponent from '~/components/AMapComponent.vue'
// 响应式数据
const mapRef = ref(null)
const centerLng = ref(120.258419)
const centerLat = ref(27.11402)
const zoomLevel = ref(17)
const viewMode = ref('2D')
const mapStatus = ref('加载中...')
const lastClick = ref(null)
const currentCenter = ref(null)
const currentZoom = ref(11)
// 计算属性
const mapCenter = computed(() => [centerLng.value, centerLat.value])
const mapStatusClass = computed(() => {
switch (mapStatus.value) {
case '地图加载完成':
return 'status-success'
case '加载中...':
return 'status-loading'
default:
return 'status-error'
}
})
// 快速定位城市
const quickLocations = [
{ name: '北京', center: [116.397428, 39.90923], zoom: 10 },
{ name: '上海', center: [121.473701, 31.230416], zoom: 10 },
{ name: '广州', center: [113.264385, 23.129163], zoom: 10 },
{ name: '深圳', center: [114.085947, 22.547], zoom: 10 },
{ name: '武汉', center: [112.397428, 31.90923], zoom: 11 },
{ name: '成都', center: [104.066541, 30.572269], zoom: 10 }
]
// 地图事件处理
const onMapReady = (mapInstance) => {
console.log('地图实例:', mapInstance)
mapStatus.value = '地图加载完成'
// 添加一个标记点
if (mapRef.value) {
mapRef.value.addMarker(mapCenter.value, {
title: '当前位置',
content: '<div style="background: #007bff; color: white; padding: 4px 8px; border-radius: 4px; font-size: 12px;">标记点</div>'
})
}
}
const onMapClick = (event) => {
lastClick.value = event
console.log('地图点击:', event)
}
const onZoomChange = (zoom) => {
currentZoom.value = zoom
console.log('缩放级别变化:', zoom)
}
const onCenterChange = (center) => {
currentCenter.value = center
centerLng.value = center.lng
centerLat.value = center.lat
console.log('中心点变化:', center)
}
// 更新中心点
const updateCenter = () => {
if (mapRef.value) {
mapRef.value.setCenter(mapCenter.value)
}
}
// 快速定位
const goToLocation = (location) => {
centerLng.value = location.center[0]
centerLat.value = location.center[1]
zoomLevel.value = location.zoom
if (mapRef.value) {
mapRef.value.setCenter(location.center)
mapRef.value.setZoom(location.zoom)
}
}
</script>
<style scoped>
.map-demo-page {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.page-header {
text-align: center;
margin-bottom: 40px;
}
.page-header h1 {
color: #333;
margin-bottom: 8px;
}
.page-header p {
color: #666;
font-size: 16px;
}
.demo-section {
margin-bottom: 40px;
background: white;
border-radius: 8px;
padding: 24px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.demo-section h2 {
color: #333;
margin-bottom: 20px;
font-size: 20px;
}
.map-controls {
display: flex;
flex-wrap: wrap;
gap: 20px;
margin-bottom: 20px;
padding: 16px;
background: #f8f9fa;
border-radius: 6px;
}
.control-group {
display: flex;
align-items: center;
gap: 8px;
}
.control-group label {
font-weight: 500;
color: #555;
white-space: nowrap;
}
.coord-input {
width: 120px;
padding: 6px 8px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
.update-btn {
background: #007bff;
color: white;
border: none;
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: background-color 0.2s;
}
.update-btn:hover {
background: #0056b3;
}
.zoom-slider {
width: 120px;
}
.zoom-value {
font-weight: 500;
color: #007bff;
min-width: 20px;
}
.view-select {
padding: 6px 8px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
.event-info {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 16px;
}
.info-item {
padding: 12px;
background: #f8f9fa;
border-radius: 6px;
border-left: 4px solid #007bff;
}
.info-item strong {
color: #333;
margin-right: 8px;
}
.status-success {
color: #28a745;
font-weight: 500;
}
.status-loading {
color: #ffc107;
font-weight: 500;
}
.status-error {
color: #dc3545;
font-weight: 500;
}
.quick-locations {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.location-btn {
background: #6c757d;
color: white;
border: none;
padding: 8px 16px;
border-radius: 20px;
cursor: pointer;
font-size: 14px;
transition: all 0.2s;
}
.location-btn:hover {
background: #5a6268;
transform: translateY(-1px);
}
/* 响应式设计 */
@media (max-width: 768px) {
.map-demo-page {
padding: 16px;
}
.map-controls {
flex-direction: column;
align-items: stretch;
}
.control-group {
justify-content: space-between;
}
.coord-input {
width: 100px;
}
.event-info {
grid-template-columns: 1fr;
}
.quick-locations {
justify-content: center;
}
}
</style>