Vue3 整合高德地图完成搜索、定位、选址功能,已封装为组件开箱即用(最新)

Vue3 整合高德地图完成搜索、定位、选址功能(最新)

  • 1、效果演示
    • 2、前端代码
      • 2.1 .env.development
      • 2.2 GaodeMap.vue
      • 2.3使用示例

1、效果演示

在这里插入图片描述

在这里插入图片描述

2、前端代码

2.1 .env.development

https://console.amap.com/dev/key/app

在这里插入图片描述

# 地图配置
VITE_AMAP_KEY = "您的高德KEY"
VITE_AMAP_SECURITY_CODE = "您的高德SECURITY_CODE"

2.2 GaodeMap.vue

<template><a-modal v-model:open="isOpen" @ok="submit" @cancel="close" width="100%" wrap-class-name="full-modal"><template #title><div ref="modalTitleRef" class="section-title">地址选择</div></template><!-- 地图容器 --><div id="container" class="map-view"></div><!-- 搜索控制面板 --><a-card class="control-panel" :bordered="false"><div><a-input-search v-model:value="searchKeyword" id="searchInput" placeholder="输入搜索关键词" enter-button@search="handleKeywordSearch" style="border-radius: 10px;" /></div><a-divider class="my-3" /><span class="mb-2">当前选定位置:</span><a-tag class="mt-2" color="#87d068"style="white-space: normal;word-wrap: break-word; overflow-wrap: break-word;font-size: 16px;padding: 8px;">{{ currentAddress }}</a-tag></a-card><div id="searchResults" style="z-index: 100 !important;max-height: 750px;border-radius: 10px;"></div></a-modal>
</template><script setup>
import locationPng from "./location.png"const props = defineProps({center: {type: Array,default: () => ["105.085476", "29.613052"], // 默认内江中心点}
});const isOpen = ref(false);
const onOpen = (record) => {isOpen.value = true;setTimeout(() => {initMap();}, 200);
}
const searchKeyword = ref("内江");
/*** 地图相关*/import AMapLoader from '@amap/amap-jsapi-loader';
const map = ref();// 地图常量配置
const currentPosition = ref([]) 			// 当前位置
const currentAddress = ref("暂无地址")		// 当前定位地址
const provinceCityDistrictInfo = ref("")		// 当前定位地址
const currentMarker = ref()					// 当前marker// 封装定位逻辑
function handleLocation(geolocation, AMap) {geolocation.getCurrentPosition((status, result) => {if (status === 'complete') {console.log('定位成功:', result)currentPosition.value = [result.position.lng, result.position.lat];getAddress(result.position.lng, result.position.lat, AMap)} else {console.warn('定位失败:', result.message)}})
}// 解析地址
function getAddress(lng, lat, AMap) {const geocoder = new AMap.Geocoder({radius: 1000,extensions: 'all',})geocoder.getAddress([lng, lat], (status, result) => {console.log(result);if (status === 'complete' && result.regeocode) {let res = result.regeocode.addressComponent;provinceCityDistrictInfo.value = res.province + res.city + res.district;currentAddress.value = result.regeocode.formattedAddress;searchKeyword.value = result.regeocode.formattedAddress;handleKeywordSearch();}})
}const poiPicker = ref(null);
const placeSearch = ref(null);
// 初始化地图
const initMap = () => {const container = document.getElementById('container');if (!container) {console.error("地图容器不存在,无法初始化");return;}window._AMapSecurityConfig = {securityJsCode: import.meta.env.VITE_AMAP_SECURITY_CODE,};AMapLoader.load({key: import.meta.env.VITE_AMAP_KEY,version: '2.0',plugins: ['AMap.Geocoder','AMap.Circle','AMap.Geolocation','AMap.CitySearch','AMap.CircleEditor','AMap.PlaceSearch','AMap.AutoComplete',],AMapUI: { // 重点就是这个version: '1.1',plugins: ['misc/PoiPicker'], // 需要加载的 AMapUI ui插件},}).then((AMap) => {const centerLngLat = new AMap.LngLat(...props.center)map.value = new AMap.Map("container", {// 设置地图容器idviewMode: "3D", // 是否为3D地图模式zoom: 10, // 初始化地图级别center: centerLngLat, // 初始化地图中心点位置});AMapUI.loadUI(['misc/PoiPicker'], (PoiPicker) => {poiPicker.value = new PoiPicker({input: 'searchInput',placeSearchOptions: {map: map.value,pageSize: 10},searchResultsContainer: 'searchResults'});console.log(poiPicker.value);poiPicker.value.on('poiPicked', (poiResult) => {const poi = poiResult.item;console.log(poi);getAddress(poi.location.lng, poi.location.lat, AMap)});poiPicker.value.searchByKeyword(searchKeyword.value.trim());});// 我的位置 添加定位控件并自动定位const geolocation = new AMap.Geolocation({enableHighAccuracy: true, // 是否使用高精度定位timeout: 10000,           // 超过10秒未获取到定位则自动失败buttonPosition: 'RB',     // 定位按钮位置(右下角)showMarker: true,         // 显示定位点showCircle: true,         // 显示定位精度圆panToLocation: true,      // 定位成功后将地图中心移动到定位位置zoomToAccuracy: true      // 定位成功后调整地图视野范围使定位位置及精度范围可见});map.value.addControl(geolocation);// 获取当前位置并判断是否在圈内handleLocation(geolocation, AMap)// ✅ 监听定位成功geolocation.on('complete', (result) => {console.log('完整定位结果:', result);currentPosition.value = [result.position.lng, result.position.lat];console.log("当前定位坐标", currentPosition.value)getAddress(result.position.lng, result.position.lat, AMap)})map.value.on('click', function (ev) {// 触发事件的地理坐标,AMap.LngLat 类型var lnglat = ev.lnglat;// 如果已经有 marker,先删除if (currentMarker.value) {map.value.remove(currentMarker.value);}currentPosition.value = [lnglat.lng, lnglat.lat];getAddress(lnglat.lng, lnglat.lat, AMap)//创建 AMap.Icon 实例:const icon = new AMap.Icon({size: new AMap.Size(32, 32), //图标尺寸imageSize: new AMap.Size(32, 32),  // 图片的原始尺寸(必须与图片文件实际尺寸一致)image: locationPng, //Icon 的图像});// 创建新的 markercurrentMarker.value = new AMap.Marker({position: lnglat,map: map.value,icon: icon, //添加 icon 图标 URLtitle: currentAddress.value,offset: new AMap.Pixel(-13, -30), //偏移量label: {content: currentAddress.value == '暂无地址' ? '请尝试再次点击' : currentAddress.value, 		// 文本内容direction: 'top', 					// 文本显示在标记的上方offset: new AMap.Pixel(0, -5),		// 偏移量,调整文本位置}});});}).catch((e) => {console.error("地图初始化失败:", e);});
};const handleKeywordSearch = () => {const keyword = searchKeyword.value.trim();if (!keyword) return;poiPicker.value.searchByKeyword(keyword);poiPicker.value.showSearchResults();
};// 声明 emit 事件
const emit = defineEmits(['address'])
const submit = () => {let res = {currentPosition: currentPosition.value,currentAddress: currentAddress.value,provinceCityDistrictInfo: provinceCityDistrictInfo.value}console.log(res);emit('address', res);isOpen.value = false;
}const close = () => {map.value.destroy()map.value = null
}// 抛出函数
defineExpose({onOpen
})
</script><style lang="less" scoped>
.gaode-map-container {position: relative;overflow: "hidden";width: 100%;height: 100%;border-radius: 8px;padding: "48px";text-align: "center";
}.map-view {width: 100%;height: 100%;border-radius: 10px;margin-top: 10px;
}.control-panel {position: absolute;top: 70px;left: 30px;width: 320px;z-index: 10;border-radius: 10px;
}.panel-header {display: flex;justify-content: space-between;align-items: center;
}.current-position {padding: 8px;background-color: #f9f9f9;border-radius: 4px;
}/*** 搜索相关*/#outer-box {height: 100%;padding-right: 300px;
}#container {height: 100%;width: 100%;
}#panel {position: absolute;top: 0;bottom: 0;right: 0;height: 100%;overflow: auto;width: 300px;z-index: 999;border-left: 1px solid #eaeaea;background: #fff;
}#searchBar {height: 30px;background: #ccc;
}#searchInput {width: 100%;height: 30px;line-height: 30%;-webkit-box-sizing: border-box;box-sizing: border-box;border: none;border-bottom: 1px solid #ccc;padding: 0 5px;
}#searchResults {top: 70px;right: 40px;position: absolute;overflow: auto;height: calc(100% - 30px);
}.amap_lib_placeSearch,
.amap-ui-poi-picker-sugg-container {border: none !important;
}.amap_lib_placeSearch .poibox.highlight {background-color: #CAE1FF;
}.poi-more {display: none !important;
}::v-deep(.amap-marker-label) {background-color: rgba(255, 255, 255, 0.9) !important;border: 1px solid #409EFF !important;/* 使用主色调边框 */border-radius: 4px !important;padding: 4px 8px !important;font-size: 13px !important;font-weight: 500 !important;/* 注意:font-weight 使用数字值 */color: #333 !important;box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15) !important;white-space: nowrap !important;
}.section-title {font-size: 16px;font-weight: 500;color: rgba(0, 0, 0, 0.85);padding-left: 8px;border-left: 4px solid #1890ff;
}
</style>

2.3使用示例

<template><a-input-search v-model:value="formData.address" placeholder="请输入地址" allow-clear enter-button="选择地址" @search="mapRef.onOpen()" /><GaodeMapTemplate ref="mapRef" @address="handleUpdateAddress" />
</template>
import GaodeMapTemplate from "./map/GaodeMap.vue";
const mapRef = ref(null)
const handleUpdateAddress = (res) => {formData.value.address = res.currentAddress;			// 地址formData.value.longitude = res.currentPosition[0];		// 经度formData.value.latitude = res.currentPosition[1];		// 纬度formData.value.level4Street = res.provinceCityDistrictInfo;  // 省市区
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/93029.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/93029.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot切换 Servlet 容器为Undertow

题目详细答案Spring Boot 默认使用 Tomcat 作为嵌入式的 Servlet 容器&#xff0c;但你也可以切换到 Undertow。Undertow 是一个轻量级、高性能的 Web 服务器和 Servlet 容器。步骤 1&#xff1a;排除 Tomcat 依赖需要在pom.xml文件&#xff08;如果使用的是 Maven&#xff09;…

通过限制对象的内存分配位置来实现特定的设计目标

《More Effective C》中的条款27聚焦于如何通过语言特性强制或禁止对象在堆上分配&#xff0c;其核心目标是通过控制内存分配位置来提升代码的安全性、可维护性和资源管理效率。 个人觉得&#xff0c;这个条款看看就可以了&#xff0c;可能在个别情况下需要考虑条款中说的情况。…

广东省省考备考(第七十四天8.12)——资料分析、数量关系(40%-70%正确率的题目)

资料分析 错题解析解析今日题目正确率&#xff1a;87% 数量关系&#xff1a;数学运算 错题解析解析备注&#xff1a; ①本题所求保护罩的表面积不包含底面。因为通常所说的“罩子”是没有底面的&#xff0c;即使罩子有底面&#xff0c;往往底面材质和罩子材质也不一样&#xff…

Java多源AI接口融合框架:动态模型切换与智能路由实战

> 在电商客服场景中,用户的一句“这件衣服适合夏天穿吗?”需要同时调用服饰知识库、天气API和风格推荐模型,但当GPT-4响应延迟时能否无缝降级到Claude?在预算有限时能否自动选择成本更低的本地模型? **多源AI接口整合已成为企业智能化落地的新基建**。据Gartner 2025报…

Linux中Docker redis介绍以及应用

一、NoSQL 1.1 单机mysql的美好时代 在90年代&#xff0c;一个网站的访问量一般都不大&#xff0c;用单个数据库完全可以轻松应付。 那个时候&#xff0c;更多的是静态网页&#xff0c;动态交互类型的网站不多。 上述架构上&#xff0c;我们来看看数据存储的瓶颈是什么&…

锅气:「现炒之魂·烟火人间」

《现炒之魂烟火人间》高清4K写实摄影方案高清4K写实摄影方案描述&#xff0c;可直接作为AI绘画工具&#xff08;如MidJourney/DALLE&#xff09;的提示词使用&#xff1a;&#x1f31f; 核心概念✅ 主题&#xff1a;中式爆炒瞬间的生命力爆发✅ 氛围&#xff1a;炽烈烟火气 神…

【力扣494】目标和

用子集法&#xff0c;选or不选变成了正or负&#xff0c;BFS执行所有情况&#xff0c;判断恰好为目标和。 灵神&#xff1a; 设所有数的和为s&#xff0c;取正的和为p&#xff0c;则和为p-(s-p)&#xff1b; 有t p-(s-p) 2p-s&#xff0c;即p (st)/2&#xff1b;这里的s和t都…

零基础AI编程开发微信小程序赚流量主广告实战

目录 前言&#xff1a;为什么选微信小程序流量主&#xff1f;零基础也能搞定的开发流程AI编程助手怎么帮忙&#xff1f;实战案例&#xff1a;做个AI图片识别小程序流量主广告怎么接入和变现&#xff1f;常见问题与避坑指南经验总结与互动1. 前言&#xff1a;为什么选微信小程序…

第六十三章:AI模型的“跨界之旅”:不同硬件架构下的兼容性方案

不同硬件架构兼容前言&#xff1a;AI的“英雄”与“舞台”第一章&#xff1a;AI硬件生态总览&#xff1a;百花齐放的“算力战场”1.1 CPU&#xff1a;AI计算的“全能基石”1.2 GPU&#xff1a;AI计算的“核心加速器”1.3 专用AI芯片&#xff1a;NPU/TPU等“定制利器”第二章&am…

2 Abp 框架核心架构

ABP Framework 核心架构 架构概述 ABP Framework 基于模块化、分层架构构建&#xff0c;遵循领域驱动设计&#xff08;DDD&#xff09;、依赖注入和 SOLID 原则&#xff0c;为构建可维护、可测试和可扩展的应用程序提供基础。 核心模块 #mermaid-svg-10g1JRKDltZN4z5P {font-fa…

Spring的高频基础面试题(二)

1. 线程池创建的作用是什么 ? 线程池的核心参数有哪些 ? 线程池执行任务的流程 ?作用&#xff1a;提高线程的复用性&#xff0c;降低损耗资源。核心参数&#xff1a;核心线程 、最大线程数 、等待空闲时间、时间单位、任务队列、线程工厂、拒绝策略执行流程&#xff1a; 首…

【JavaEE】(12) 创建一个 Sring Boot 项目

一、Maven 1、什么是 Maven Maven 用于管理项目、管理依赖&#xff08;通过 POM 文件配置各种各样的 jar 包&#xff09;。 在没有 Maven 之前&#xff0c;需要手动将 jar 包导入项目。整个流程&#xff1a;从网上查 jar 包并下载到本地&#xff08;或者叫同事发&#xff09;&…

最终章【1】Epson机器人篇

1,开发环境 Epson RC 7.5.1 RC90控制器 2,条件分支指令 2.1,If...EndIf,逻辑判断分支 语法格式: If 条件1 Then 处理逻辑1................ ElseIf 条件2 Then 处理逻辑2................ Else 处理逻辑3................ EndIf 例子: String order$If ord…

vue3 实现web网页不同分辨率适配

vue3 实现web网页不同分辨率适配首先这个标题可能不是特别的合适&#xff0c;之前开发了一个网站&#xff0c;那个网站是类似于官网的效果&#xff0c;按照 19201080100% 的分辨率进行开发的&#xff0c;但是在开发完成之后&#xff0c;发现有的电脑是 19201080125% 的大小展示…

电子电路原理学习笔记---第5章特殊用途二极管---第2天

5.5阅读数据手册图5-15给出了1N957B和1N4728A系列的齐纳二极管数据手册中的数据&#xff0c;再后面的讨论中将参考这些数据。数据手册中大部分信息是提供给电路设计者的&#xff0c;但有些内容在故障诊断和测试时也有必要了解。5.5.1最大功率齐纳二极管的功率等于它对应的电压与…

实现一个二维码让 iOS 和 Android 用户自动跳转到对应下载链接

实现一个二维码让 iOS 和 Android 用户自动跳转到对应下载链接 背景 开发一个APP后&#xff0c;需要分发Android测试包和iOS TestFlight的场景&#xff0c;但为两个端分别生成二维码&#xff0c;需要为二维码标识系统以免导致用户扫错码。如何实现一个二维码让 iOS 和 Androi…

Docker中ES安装分词器

1、下载好的文件上传到虚拟机或者云服务器 https://release.infinilabs.com/analysis-ik/stable/ elasticsearch-analysis-ik-8.10.4.zip 2、将本地 ZIP 文件复制到容器内的临时目录&#xff08;如 /tmp/&#xff09; docker cp /data/elasticsearch-analysis-ik-8.10.4.zip e…

掌握while循环:C语言编程基础

目录 一、while循环简介 二、if和while的对比 语法结构对比&#xff1a; 实际代码对比&#xff1a; 三、while语句的执行流程 while循环的执行流程如下&#xff1a; 流程图表示&#xff1a; 四、while循环实践 练习&#xff1a;在屏幕上打印1~10的值 五、进阶练习 题…

XML Schemas 简介

XML Schemas 简介 引言 XML(可扩展标记语言)是互联网上用于数据交换的一种标准标记语言。随着互联网技术的飞速发展,XML因其灵活性和可扩展性而被广泛应用于各种领域。XML Schemas(XML模式)作为一种定义XML文档结构的机制,为XML文档提供了严格的规范,确保了数据的准确…

Gradle(二)Gradle的优势、项目结构介绍

目录一、什么是 Gradle&#xff1f;二、为什么选择 Gradle&#xff1f;三、Gradle 的项目结构3.1 项目结构3.2 gradle wrapper 包装器3.3 settings.gradle 设置文件3.4 build.gradle 核心构建文件1&#xff09;原始文件内容2&#xff09;plugins 插件3&#xff09;repositories…