vue实现地图地址搜索小功能
如果遇到import标红问题,是由于Vue 文件中的 JavaScript 代码通常需要通过 Babel 转译,而 ESLint 默认会检查 Babel 配置文件(如 .babelrc 或 babel.config.js)。在src/components目录下创建一个新的组件 MapView.vue(App.vue只负责组织页面结构,而不是直接包含所有地图功能逻辑。添加Leaflet的CSS架构:
1.确保安装好node.js(https://nodejs.org/zh-cn)和npm
node -v
npm -v
npm install -g npm@latest
申请一个高德API
2.创建VUE项目(新建目录,通过Vscode打开),进入项目目录,打开终端(Crtl+~)
npm install -g @vue/cli
vue create vue-leaflet-map
cd vue-leaflet-map
npm i
下载时网速慢,如果遇到问题/解决方法:切换淘宝镜像源——npm config set registry https://registry.npmmirror.com/
3.安装Leaflet库,npm install leaflet
添加Leaflet的CSS架构:打开 src/main.js 文件,导入 Leaflet的 CSS 文件。
添加:import 'leaflet/dist/leaflet.css';
如果遇到import标红问题,是由于Vue 文件中的 JavaScript 代码通常需要通过 Babel 转译,而 ESLint 默认会检查 Babel 配置文件(如 .babelrc 或 babel.config.js)。如果没有找到配置文件,或者 ESLint 配置没有禁用 requireConfigFile 选项,就会抛出这个错误。
解决方案:
- 在babel.config.js中,修改为:
module.exports = {
presets: [
'@babel/preset-env' // 确保使用符合现代 JavaScript 的转译规则
]
};
重新在终端安装依赖:npm install --save-dev @babel/core @babel/preset-env
- 在.eslintrc.js中,修改为:
module.exports = {
root: true,
env: {
node: true
},
'extends': [
'plugin:vue/vue3-essential',
'eslint:recommended'
],
parserOptions: {
requireConfigFile: false // 禁用 Babel 配置文件检查
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
}
}
4.创建地图组件
在src/components目录下创建一个新的组件 MapView.vue(App.vue只负责组织页面结构,而不是直接包含所有地图功能逻辑。)
5.打开MapView.vue,添加代码:
<template> <div id="map" ref="mapContainer" style="height: 900px;"></div> </template> <script> import L from 'leaflet'; import 'leaflet/dist/leaflet.css'; export default { name: 'MapView', data(){ return{ map: null, amapKey: '', // 高德 API Key baseLayer: { '高德地图底图': L.tileLayer("https://webrd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}", { attribution: "高德", maxZoom: 20 }), '卫星影像地图': L.tileLayer("https://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}.png", { attribution: "卫星影像", maxZoom: 20 }), 'OpenStreetMap': L.tileLayer("http://10.87.211.254:8099/title/{z}/{x}/{y}.png", { attribution: "白色底图", maxZoom: 20 }), '天地图影像图': L.tileLayer("http://t3.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=d0cf74b31931aab68af181d23fa23d8d", { maxZoom: 20 }), '天地图街道图': L.tileLayer("http://t4.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=d0cf74b31931aab68af181d23fa23d8d", { maxZoom: 20 }) } }; }, mounted() { this.initMap(); // 初始化地图 }, methods: { initMap() { // 初始化地图 this.map = L.map(this.$refs.mapContainer, { center: [34.81732, 113.535807], zoom: 15, zoomAnimation: false,// 禁用缩放动画 zoomControl: false, // 自定义缩放控件 });
// 添加底层图层 L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap', maxZoom: 20 }).addTo(this.map); L.marker([34.81732, 113.535807], { icon: L.icon({ iconUrl: require('@/assets/logo.png'), // 确保路径正确 iconSize: [40, 40], iconAnchor: [20, 40], popupAnchor: [0, -30], }), }) .addTo(this.map) .bindPopup('这是郑州大学!') .openPopup(); // 添加图层切换控件 L.control.layers(this.baseLayer, {}, { position: 'topleft' }).addTo(this.map); }, }, }; </script> <style> #map { width: 100%; height: 100vh; position: relative; border-radius: 10px; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2); transition: transform 0.3s ease; z-index: 1; } </style> |
打开 src/App.vue 文件,并在其中引入MapView 组件。修改 App.vue:
<template> <div id="app"> <Map /> </div> </template> <script> import Map from './components/MapView.vue'; export default { name: 'App', components: { Map } }; </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; text-align: center; color: #2c3e50; margin-top: 60px; } </style> |
6.运行项目 npm run serve
注意:在本地开发环境中,Vue CLI 默认会显示两个地址:
Local (本地):http://localhost:8083/
这是你的应用在当前计算机上的本地地址,只有在这台计算机上才能访问。
Network (网络):http://192.168.2.238:8083/
这是你的应用在局域网中的地址,显示的是你电脑的局域网 IP 地址。
7.实现地图地址搜索功能
<template> <div> <div id="map" ref="mapContainer" style="height: 900px;"> <!-- 搜索框 --> <div class="map-search-container"> <input type="text" v-model="searchQuery" @input="handleSearchInput" placeholder="查找地点..." class="map-search-box" /> <div v-if="searchResults.length > 0" class="search-results"> <ul> <li v-for="(result, index) in searchResults" :key="index" @click="selectSearchResult(result)"> {{ result.name }} </li> </ul> </div> </div> </div> </div>
</template> <script> import L from 'leaflet'; import 'leaflet/dist/leaflet.css'; import axios from 'axios'; export default { name: 'MapView', data(){ return{ map: null, amapKey: '', // 高德 API Key searchQuery: '', // 搜索框输入的内容 searchResults: [], // 搜索结果 baseLayer: { '高德地图底图': L.tileLayer("https://webrd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}", { attribution: "高德", maxZoom: 20 }), '卫星影像地图': L.tileLayer("https://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}.png", { attribution: "卫星影像", maxZoom: 20 }), 'OpenStreetMap': L.tileLayer("http://10.87.211.254:8099/title/{z}/{x}/{y}.png", { attribution: "白色底图", maxZoom: 20 }), '天地图影像图': L.tileLayer("http://t3.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=d0cf74b31931aab68af181d23fa23d8d", { maxZoom: 20 }), '天地图街道图': L.tileLayer("http://t4.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=d0cf74b31931aab68af181d23fa23d8d", { maxZoom: 20 }) } }; }, mounted() { this.initMap(); // 初始化地图 }, methods: { initMap() { // 初始化地图 this.map = L.map(this.$refs.mapContainer, { center: [34.81732, 113.535807], zoom: 15, zoomAnimation: false,// 禁用缩放动画 zoomControl: false, // 自定义缩放控件 });
// 添加底层图层 L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap', maxZoom: 20 }).addTo(this.map); L.marker([34.81732, 113.535807], { icon: L.icon({ iconUrl: require('@/assets/icon.jpg'), // 确保路径正确 iconSize: [23, 30], iconAnchor: [20, 40], popupAnchor: [0, -30], }), }) .addTo(this.map) .bindPopup('这是郑州大学!') .openPopup(); // 添加图层切换控件 L.control.layers(this.baseLayer, {}, { position: 'topleft' }).addTo(this.map); }, // 处理搜索框输入 handleSearchInput() { if (this.searchQuery.length > 2) { this.searchWithAmapAPI(this.searchQuery); } else { this.searchResults = []; // 清空搜索结果 } }, // 使用高德 API 进行地址搜索 async searchWithAmapAPI(query) { try { const response = await axios.get('https://restapi.amap.com/v3/place/text', { params: { key: this.amapKey, keywords: query, city: '全国', // 可以根据需要指定城市 output: 'json', }, }); if (response.data.status === '1') { // 解析高德API返回的地点列表 this.searchResults = response.data.pois.map((poi) => ({ name: poi.name, location: poi.location.split(',').reverse().map(Number), // 经纬度转为 [lat, lng] 格式 address: poi.address, })); } else { this.searchResults = []; } } catch (error) { console.error('高德API调用失败', error); } }, // 选择搜索结果 selectSearchResult(result) { const latlng = result.location; this.searchResults = []; // 清空搜索结果 this.searchQuery = result.name; // 移动地图到该位置并添加标记 this.$nextTick(() => { this.map.panTo(latlng); this.addMarker(latlng, L.icon({ iconUrl: require('@/assets/icon.jpg'), iconSize: [40, 40], iconAnchor: [20, 40], popupAnchor: [0, -30], }), `<b>${result.name}</b><br>${result.address || ''}`); }); }, // 添加标记到地图 addMarker(latlng, icon, popupContent) { const marker = L.marker(latlng, { icon }) .addTo(this.map) .bindPopup(popupContent) .openPopup(); return marker; }, }, }; </script> <style> #map { width: 100%; height: 100vh; position: relative; border-radius: 10px; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2); transition: transform 0.3s ease; z-index: 1; } /* 搜索框样式,放置在地图容器内部 */ .map-search-container { position: absolute; top: 70px; left: 10px; z-index: 1000; width: 250px; } .map-search-box { width: 100%; padding: 12px; border-radius: 25px; border: 1px solid #ddd; font-size: 16px; box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1); transition: all 0.3s ease; } .map-search-box:focus { outline: none; border-color: #6e8efb; box-shadow: 0 0 10px rgba(110, 143, 251, 0.5); } .search-results { position: absolute; top: 40px; left: 0; width: 100%; background-color: white; border: 1px solid #ddd; border-radius: 5px; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2); z-index: 1001; } .search-results ul { list-style: none; padding: 0; margin: 0; } .search-results li { padding: 10px; cursor: pointer; transition: background-color 0.3s ease; } .search-results li:hover { background-color: #f0f0f0; } </style> |
更多推荐
所有评论(0)