| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463 |
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Vue2 百度地图位置搜索</title>
- <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.min.js"></script>
- <script src="https://unpkg.com/vue-baidu-map"></script>
- <style>
- * {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
- font-family: 'Microsoft YaHei', sans-serif;
- }
- body {
- background-color: #f5f7fa;
- color: #333;
- line-height: 1.6;
- }
- .container {
- max-width: 1200px;
- margin: 0 auto;
- padding: 20px;
- }
- header {
- text-align: center;
- margin-bottom: 30px;
- padding: 20px;
- background: linear-gradient(135deg, #3385ff 0%, #2d6cfa 100%);
- color: white;
- border-radius: 10px;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
- }
- h1 {
- font-size: 2.2rem;
- margin-bottom: 10px;
- }
- .subtitle {
- font-size: 1.1rem;
- opacity: 0.9;
- }
- .app-container {
- display: flex;
- flex-wrap: wrap;
- gap: 20px;
- }
- .map-section {
- flex: 2;
- min-width: 300px;
- }
- .info-section {
- flex: 1;
- min-width: 300px;
- background: white;
- border-radius: 10px;
- padding: 20px;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
- }
- .map-container {
- width: 100%;
- height: 500px;
- border-radius: 10px;
- overflow: hidden;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
- }
- .search-box {
- display: flex;
- margin-bottom: 20px;
- }
- .search-input {
- flex: 1;
- padding: 12px 15px;
- border: 1px solid #ddd;
- border-radius: 5px 0 0 5px;
- font-size: 16px;
- outline: none;
- transition: border 0.3s;
- }
- .search-input:focus {
- border-color: #3385ff;
- }
- .search-btn {
- padding: 0 20px;
- background: #3385ff;
- color: white;
- border: none;
- border-radius: 0 5px 5px 0;
- cursor: pointer;
- font-size: 16px;
- transition: background 0.3s;
- }
- .search-btn:hover {
- background: #2d6cfa;
- }
- .location-info {
- margin-top: 20px;
- padding: 15px;
- background: #f8f9fa;
- border-radius: 8px;
- border-left: 4px solid #3385ff;
- }
- .info-title {
- font-weight: bold;
- margin-bottom: 10px;
- color: #3385ff;
- display: flex;
- align-items: center;
- }
- .info-title i {
- margin-right: 8px;
- }
- .coordinates, .address {
- margin: 8px 0;
- padding: 8px 0;
- border-bottom: 1px dashed #e0e0e0;
- }
- .coordinates span, .address span {
- font-weight: bold;
- color: #555;
- }
- .coordinate-row {
- display: flex;
- justify-content: space-between;
- margin-bottom: 8px;
- }
- .coordinate-system {
- font-weight: bold;
- color: #3385ff;
- }
- .coordinate-value {
- font-family: monospace;
- background: #eef5ff;
- padding: 2px 6px;
- border-radius: 4px;
- }
- .instruction {
- margin-top: 20px;
- padding: 15px;
- background: #e8f4ff;
- border-radius: 8px;
- font-size: 14px;
- color: #2c3e50;
- }
- .search-results {
- margin-top: 20px;
- max-height: 300px;
- overflow-y: auto;
- border: 1px solid #e0e0e0;
- border-radius: 8px;
- }
- .result-item {
- padding: 10px 15px;
- border-bottom: 1px solid #eee;
- cursor: pointer;
- transition: background 0.2s;
- }
- .result-item:hover {
- background: #f0f7ff;
- }
- .result-item:last-child {
- border-bottom: none;
- }
- .result-name {
- font-weight: bold;
- margin-bottom: 5px;
- color: #3385ff;
- }
- .result-address {
- font-size: 14px;
- color: #666;
- }
- .result-distance {
- font-size: 12px;
- color: #888;
- margin-top: 4px;
- }
- footer {
- text-align: center;
- margin-top: 30px;
- padding: 20px;
- color: #666;
- font-size: 14px;
- }
- .status-message {
- padding: 10px;
- margin: 10px 0;
- border-radius: 5px;
- text-align: center;
- }
- .status-success {
- background-color: #e8f5e9;
- color: #2e7d32;
- }
- .status-error {
- background-color: #ffebee;
- color: #c62828;
- }
- .loading {
- display: inline-block;
- width: 20px;
- height: 20px;
- border: 3px solid #f3f3f3;
- border-top: 3px solid #3385ff;
- border-radius: 50%;
- animation: spin 1s linear infinite;
- margin-right: 10px;
- }
- @keyframes spin {
- 0% { transform: rotate(0deg); }
- 100% { transform: rotate(360deg); }
- }
- @media (max-width: 768px) {
- .app-container {
- flex-direction: column;
- }
- .map-container {
- height: 300px;
- }
- }
- </style>
- </head>
- <body>
- <div id="app" class="container">
- <header>
- <h1>Vue2 百度地图位置搜索</h1>
- <p class="subtitle">使用 vue-baidu-map 插件实现位置搜索功能</p>
- </header>
- <div class="app-container">
- <div class="map-section">
- <div class="search-box">
- <input type="text" v-model="searchKeyword" class="search-input" placeholder="输入地点名称进行搜索..." @keyup.enter="searchPlace">
- <button @click="searchPlace" class="search-btn">搜索</button>
- </div>
- <div v-if="statusMessage" class="status-message" :class="statusClass">
- {{ statusMessage }}
- </div>
- <!-- 百度地图容器 -->
- <baidu-map class="map-container"
- :center="mapCenter"
- :zoom="zoom"
- :scroll-wheel-zoom="true"
- @ready="mapReady"
- @click="mapClick">
- <!-- 地图标记 -->
- <bm-marker :position="markerPosition"
- :dragging="true"
- @dragend="markerDragEnd"
- v-if="markerPosition.lng">
- </bm-marker>
- <!-- 本地搜索 -->
- <bm-local-search :keyword="searchKeyword"
- :auto-viewport="true"
- :location="searchLocation"
- @searchcomplete="searchComplete"
- @infohtmlset="infoHtmlSet"
- v-if="searchKeyword && isMapReady">
- </bm-local-search>
- </baidu-map>
- </div>
- <div class="info-section">
- <h2 class="info-title"><i>📍</i> 位置信息</h2>
- <div v-if="selectedLocation" class="location-info">
- <div class="coordinates">
- <div class="coordinate-row">
- <span class="coordinate-system">经纬度:</span>
- <span class="coordinate-value">{{ selectedLocation.lng.toFixed(6) }}, {{ selectedLocation.lat.toFixed(6) }}</span>
- </div>
- </div>
- <div class="address">
- <span>详细地址:</span>
- {{ selectedLocation.address || '正在获取中...' }}
- </div>
- </div>
- <div v-else class="instruction">
- 请点击地图上的任意位置,或使用搜索功能选择地点,此处将显示该位置的坐标信息和详细地址。
- </div>
- <div v-if="searchResults.length > 0" class="search-results">
- <h3>搜索结果 ({{ searchResults.length }})</h3>
- <div v-for="(result, index) in searchResults" :key="index"
- class="result-item" @click="selectSearchResult(result)">
- <div class="result-name">{{ result.title }}</div>
- <div class="result-address">{{ result.address }}</div>
- <div class="result-distance" v-if="result.distance">距离: {{ result.distance }}米</div>
- </div>
- </div>
- </div>
- </div>
- <footer>
- <p>Vue2 + 百度地图位置搜索示例 | 使用 vue-baidu-map 插件</p>
- </footer>
- </div>
- <script>
- // 配置百度地图AK(实际使用时请替换为您的AK)
- Vue.use(window.VueBaiduMap.default, {
- ak: '您的百度地图AK'
- });
- new Vue({
- el: '#app',
- data: {
- map: null,
- BMap: null,
- isMapReady: false,
- mapCenter: {lng: 116.404, lat: 39.915}, // 默认中心点(北京)
- zoom: 12,
- searchKeyword: '',
- searchLocation: '北京',
- selectedLocation: null,
- markerPosition: {},
- searchResults: [],
- statusMessage: '',
- statusClass: ''
- },
- mounted() {
- // 组件挂载后,地图会在ready回调中初始化
- },
- methods: {
- // 地图初始化完成回调
- mapReady({BMap, map}) {
- this.BMap = BMap;
- this.map = map;
- this.isMapReady = true;
- this.showStatus('地图加载完成', 'status-success');
- // 添加地图控件
- map.addControl(new BMap.NavigationControl());
- map.addControl(new BMap.ScaleControl());
- map.addControl(new BMap.OverviewMapControl());
- console.log('百度地图初始化完成');
- },
- // 地图点击事件
- mapClick(e) {
- if (!this.isMapReady) return;
- const point = e.point;
- this.markerPosition = {lng: point.lng, lat: point.lat};
- // 使用逆地理编码获取地址
- const geocoder = new this.BMap.Geocoder();
- geocoder.getLocation(point, (result) => {
- if (result) {
- this.selectedLocation = {
- lng: point.lng,
- lat: point.lat,
- address: result.address
- };
- this.showStatus('位置选择成功', 'status-success');
- }
- });
- },
- // 标记点拖拽结束
- markerDragEnd(e) {
- const point = e.point;
- this.markerPosition = {lng: point.lng, lat: point.lat};
- // 使用逆地理编码获取地址
- const geocoder = new this.BMap.Geocoder();
- geocoder.getLocation(point, (result) => {
- if (result) {
- this.selectedLocation = {
- lng: point.lng,
- lat: point.lat,
- address: result.address
- };
- this.showStatus('位置已更新', 'status-success');
- }
- });
- },
- // 执行地点搜索
- searchPlace() {
- if (!this.searchKeyword.trim()) {
- this.showStatus('请输入搜索关键词', 'status-error');
- return;
- }
- if (!this.isMapReady) {
- this.showStatus('地图尚未加载完成,请稍后再试', 'status-error');
- return;
- }
- this.showStatus('搜索中...', '');
- console.log('搜索关键词:', this.searchKeyword);
- // 清空之前的结果
- this.searchResults = [];
- },
- // 搜索完成回调
- searchComplete(results) {
- if (!results) return;
- // 将搜索结果转换为简单格式
- this.searchResults = results.Kr && results.Kr.map(item => {
- return {
- title: item.title,
- address: item.address,
- point: item.point,
- distance: item.distance || null
- };
- }) || [];
- if (this.searchResults.length > 0) {
- this.showStatus(`找到 ${this.searchResults.length} 个结果`, 'status-success');
- } else {
- this.showStatus('未找到相关地点', 'status-error');
- }
- console.log('搜索结果:', this.searchResults);
- },
- // 信息窗口内容设置回调
- infoHtmlSet(e) {
- // 可以在这里处理信息窗口内容
- console.log('信息窗口内容:', e);
- },
- // 选择搜索结果
- selectSearchResult(result) {
- this.markerPosition = {lng: result.point.lng, lat: result.point.lat};
- this.mapCenter = this.markerPosition;
- this.zoom = 16;
- this.selectedLocation = {
- lng: result.point.lng,
- lat: result.point.lat,
- address: result.address
- };
- this.showStatus(`已选择: ${result.title}`, 'status-success');
- },
- // 显示状态消息
- showStatus(message, className) {
- this.statusMessage = message;
- this.statusClass = className;
- // 3秒后自动清除消息
- if (className !== '') {
- setTimeout(() => {
- this.statusMessage = '';
- }, 3000);
- }
- }
- }
- });
- </script>
- </body>
- </html>
|