如何在Vue.js中实现Leaflet地图的L.Control.Search全局搜索与双图层切换
Vue.js + Leaflet.js 实现地图应用(含展示、搜索、图层切换)
1. 安装依赖
先在Vue项目里装必要的包:
# Vue 3 项目 npm install leaflet @vue-leaflet/vue-leaflet # 位置搜索插件 npm install leaflet-geosearch # Vue 2 项目替换为 # npm install leaflet vue2-leaflet
记得在main.js或组件里引入Leaflet样式:
import 'leaflet/dist/leaflet.css'
2. 完整组件实现
下面是包含所有功能的地图组件代码:
模板部分
<template> <div class="map-wrapper"> <l-map ref="mapRef" :zoom="initZoom" :center="initCenter"> <!-- OpenStreetMap 图层 --> <l-tile-layer ref="osmLayer" url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" attribution="© OpenStreetMap contributors" ></l-tile-layer> <!-- 高德地图图层 --> <l-tile-layer ref="amapLayer" url="https://webst0{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}" attribution="© 高德地图" :visible="false" ></l-tile-layer> </l-map> <!-- 功能操作区 --> <div class="map-tools"> <button @click="switchLayer">切换地图图层</button> <input type="text" v-model="searchKeyword" @input="triggerSearch" placeholder="搜索城市/地点..." /> </div> </div> </template>
脚本部分
<script setup> import { ref, onMounted } from 'vue' import { LMap, LTileLayer } from '@vue-leaflet/vue-leaflet' import L from 'leaflet' import { OpenStreetMapProvider } from 'leaflet-geosearch' // 地图基础配置 const initZoom = ref(13) const initCenter = ref([39.908860, 116.397390]) // 默认北京坐标 const mapRef = ref(null) const osmLayer = ref(null) const amapLayer = ref(null) const searchKeyword = ref('') let searchControl = null let searchMarkers = [] // 存搜索结果标记,方便后续清除 // 修复Leaflet默认图标路径问题 delete L.Icon.Default.prototype._getIconUrl L.Icon.Default.mergeOptions({ iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'), iconUrl: require('leaflet/dist/images/marker-icon.png'), shadowUrl: require('leaflet/dist/images/marker-shadow.png'), }) onMounted(() => { const mapInstance = mapRef.value.mapObject // 初始化搜索控件 const searchProvider = new OpenStreetMapProvider() searchControl = new window.GeoSearch.GeoSearchControl({ provider: searchProvider, style: 'bar', autoClose: true, keepResult: false }) mapInstance.addControl(searchControl) // 监听搜索结果,添加标记 mapInstance.on('geosearch/showlocation', (res) => { // 清除旧标记 searchMarkers.forEach(marker => mapInstance.removeLayer(marker)) searchMarkers = [] // 添加新标记并弹出信息框 const marker = L.marker(res.location.coordinates).addTo(mapInstance) marker.bindPopup(res.location.label).openPopup() searchMarkers.push(marker) }) }) // 切换图层逻辑 const switchLayer = () => { const isOsmVisible = osmLayer.value.visible osmLayer.value.visible = !isOsmVisible amapLayer.value.visible = isOsmVisible } // 手动触发搜索(配合自定义输入框) const triggerSearch = () => { if (searchKeyword.value && searchControl) { searchControl.search(searchKeyword.value) } } </script>
样式部分
<style scoped> .map-wrapper { position: relative; width: 100%; height: 80vh; } .map-tools { position: absolute; top: 20px; right: 20px; display: flex; gap: 12px; z-index: 1000; } .map-tools input { padding: 8px 14px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px; } .map-tools button { padding: 8px 18px; border: none; border-radius: 4px; background-color: #42b983; color: #fff; cursor: pointer; } .map-tools button:hover { background-color: #359469; } </style>
3. 功能细节说明
地图展示
- 用
l-map作为核心容器,通过zoom和center设置初始状态 l-tile-layer加载瓦片地图,支持自定义第三方瓦片URL(示例用了OSM和高德)
全局位置搜索
- 依赖
leaflet-geosearch插件,默认用OpenStreetMap的搜索服务,也可替换为Google、Bing等provider - 通过监听
geosearch/showlocation事件处理结果,自动清除旧标记避免堆积
图层切换
- 控制两个
l-tile-layer的visible属性实现切换;也可以用Leaflet原生的图层控制面板,代码如下:
// 在onMounted中添加 const baseLayers = { 'OpenStreetMap': osmLayer.value.tileLayerObject, '高德地图': amapLayer.value.tileLayerObject } L.control.layers(baseLayers).addTo(mapInstance)
内容的提问来源于stack exchange,提问作者Ujang Aripin
相关产品推荐
相关产品推荐

