vue2+UniApp微信小程序集成高德地图

技术文章大纲:UniApp微信小程序引入高德地图

准备工作

开发指南https://lbs.amap.com/api/wx/gettingstarted

  • 注册高德地图开发者账号并申请小程序应用的Key
  • 确保UniApp项目已配置微信小程序平台支持
  • 了解微信小程序与高德地图API的兼容性限制

高德地图SDK引入

  • 下载高德地图微信小程序JavaScript SDK

  • https://lbs.amap.com/api/wx/download

  • 将SDK文件放置于UniApp项目静态资源目录

  • const amapFile = require('@/libs/amap-wx.130.js')

基础地图功能实现

  • 在页面中声明map组件,使用的是uniapp的map组件
  • https://uniapp.dcloud.net.cn/component/map.html#map
  • 注:因为地图服务商问题,引入高德地图api但是显示是腾讯地图
  • 模板中嵌入地图组件并设置初始经纬度
  • 通过CSS调整地图容器样式与尺寸
javascript 复制代码
<template>
	<view class="map-location-component">
		<view class="map-container">
			<view class="search-bar">
				地址:<u-input v-model="searchKeyword" placeholder="请输入地址关键词搜索" 
				@input="handleSearch" class="search-input" clearable shape="circle"></u-input>
				
			</view>
			<view v-if="poiList.length > 0" class="poi-list">
				<view v-for="poi in poiList" :key="poi.id" class="poi-item" @click="selectPoi(poi)">
					<view class="poi-content">
						<view class="poi-name">{{ poi.name }}</view>
						<view class="poi-address">{{ poi.address }}</view>
					</view>
				</view>
			</view>
			<!-- 地图容器 -->
			<map id="amap-container" class="amap-container" :longitude="longitude" :latitude="latitude"
				:markers="markers" :scale="16" @tap="handleMapClick" show-location></map>
		</view>
	</view>
</template>

<script>
	const amapFile = require('@/libs/amap-wx.130.js')
	export default {
		name: 'MapLocation',
		data() {
			return {
				searchKeyword: '',
				searchLoading: false,
				locationLoading: false,
				poiList: [],
				longitude: '',
				latitude: '',
				markers: [],
				selectedLocation: null,
				searchTimer: null,
				amapKey: '地图key'
			}
		},
		mounted() {
			this.initMap()
		},
		methods: {
			//初始化位置
			setInitialLocation(coordinates, address) {
				if (!this.amap) {
					this.initMap()
				}
				if (coordinates && address) {
					const [lng, lat] = coordinates.split(',').map(Number)
					this.longitude = lng
					this.latitude = lat
					this.selectedLocation = {
						coordinates,
						address
					}
					this.searchKeyword = address
					this.markers = [{
						id: 1,
						longitude: lng,
						latitude: lat,
						title: address,
						width: 30,
						height: 30
					}]
					this.confirmSelection()
				}
			},
			confirmSelection() {
				if (this.selectedLocation) {
					this.$emit('confirm', this.selectedLocation)
				}
			},
			// 初始化地图
			initMap() {
				if (!this.amap) {
					this.amap = new amapFile.AMapWX({
						key: this.amapKey
					})
				}
			},
			// 获取当前位置
			getCurrentLocation() {
				uni.showLoading({
					title: '定位中...'
				})
				this.amap.getRegeo({
					success: (res) => {
						uni.hideLoading()
						const {
							longitude,
							latitude
						} = res[0]
						const address = res[0].name || res[0].desc
						this.longitude = longitude
						this.latitude = latitude
						const locationStr = `${longitude},${latitude}`
						this.markers = [{
							id: 1,
							longitude,
							latitude,
							title: address,
							width: 30,
							height: 30
						}]
						this.searchKeyword = address
						this.selectedLocation = {
							coordinates: locationStr,
							address: address
						};
						this.confirmSelection()
					},
					fail: (err) => {
						uni.hideLoading()
						uni.showToast({
							title: '定位失败',
							icon: 'none'
						})
						console.error('定位失败:', err)
					}
				})
			},
			// 搜索地址
			handleSearch() {
				if (!this.searchKeyword.trim()) {
					this.poiList = []
					return
				}
				clearTimeout(this.searchTimer)
				this.searchTimer = setTimeout(() => {
					this.amap.getInputtips({
						keywords: this.searchKeyword,
						city: '',
						success: (res) => {
							this.poiList = res.tips.filter(item => item.location)
						},
						fail: () => {
							uni.showToast({
								title: '搜索失败',
								icon: 'none'
							})
						}
					})
				}, 500)
			},
			selectPoi(item) {
				const address = item.name
				this.searchKeyword = address
				const [lng, lat] = item.location.split(',').map(Number)
				const locationStr = `${lng},${lat}`
				this.longitude = lng
				this.latitude = lat
				this.markers = [{
					id: 1,
					longitude: lng,
					latitude: lat,
					title: address,
					width: 30,
					height: 30
				}]
				this.poiList = []
				this.selectedLocation = {
					coordinates: locationStr,
					address: address
				};
				this.confirmSelection()
			},

			handleMapClick(e) {
				const lng = e.detail.longitude
				const lat = e.detail.latitude
				this.getAddressByLocation(lng, lat)
			},
			getAddressByLocation(lng, lat) {
				this.amap.getRegeo({
					location: `${lng},${lat}`,
					success: (res) => {
						const lng = res[0].longitude
						const lat = res[0].latitude
						const locationStr = `${lng},${lat}`
						const address = res[0].regeocodeData.formatted_address
						this.searchKeyword = address
						this.markers = [{
							id: 1,
							longitude: lng,
							latitude: lat,
							title: address,
							width: 30,
							height: 30,
						}];
						this.selectedLocation = {
							coordinates: locationStr,
							address: address
						};
						this.confirmSelection()
					}
				})
			}
		}
	}
</script>

<style scoped>
	.map-location-component {
		/* padding: 16rpx; */
		box-sizing: border-box;
	}

	.map-container {
		width: 100%;
	}

	.search-bar {
		display: flex;
		align-items: center;
		margin-bottom: 20rpx;
		position: relative;
	}

	.search-input {
		flex: 1;
		padding: 0 20rpx;
		border: 1px solid #dcdfe6;
		border-radius: 40rpx;
		font-size: 28rpx;
	}

	.clear-btn {
		position: absolute;
		right: 20rpx;
		width: 50rpx;
		height: 50rpx;
		line-height: 50rpx;
		text-align: center;
		font-size: 36rpx;
		color: #999;
		background: transparent;
		padding: 0;
	}

	.poi-list {
		max-height: 400rpx;
		overflow-y: auto;
		border: 1px solid #ebeef5;
		border-radius: 16rpx;
		margin-bottom: 20rpx;
	}

	.poi-item {
		padding: 20rpx;
		border-bottom: 1px solid #f5f5f5;
		cursor: pointer;
	}

	.poi-item:last-child {
		border-bottom: none;
	}

	.poi-item:active {
		background-color: #f5f7fa;
	}

	.poi-name {
		font-weight: bold;
		color: #303133;
		font-size: 30rpx;
		margin-bottom: 8rpx;
	}

	.poi-address {
		font-size: 26rpx;
		color: #606266;
	}

	.amap-container {
		width: 100%;
		height: 600rpx;
		border-radius: 16rpx;
		margin-bottom: 20rpx;
	}

	.btn-group {
		display: flex;
		gap: 20rpx;
	}

	.get-location-btn,
	.confirm-btn {
		flex: 1;
		height: 88rpx;
		line-height: 88rpx;
		font-size: 30rpx;
		border-radius: 16rpx;
	}

	.get-location-btn {
		background-color: #f5f7fa;
		color: #303133;
	}

	.confirm-btn {
		background-color: #007aff;
		color: #fff;
	}

	.confirm-btn:disabled {
		background-color: #b3d4fc;
	}
</style>

引入:

javascript 复制代码
<template>
  <MapLocation @confirm="handleLocationConfirm" ref="mapLocation"></MapLocation>
</template>
<script>
import MapLocation from "@/components/MapLocation.vue";
export default{
components: {
    MapLocation
  },
}
</script>

需要引入地图的方法里调用定位到当前位置:this.$refs.mapLocation.getCurrentLocation();

已有经纬度坐标和位置调用定位到已有位置:this.$refs.mapLocation.setInitialLocation(lng, lat); // lng:经度 lat:纬度

地图交互功能扩展

  • 监听地图缩放、拖动等事件
  • 添加标记点并实现点击弹窗
  • 集成位置搜索与路线规划功能

性能优化与注意事项

  • 控制地图渲染频率避免性能损耗
  • 处理微信小程序与H5环境差异
  • 遵守高德地图API调用频次限制

调试与发布

  • 使用真机调试解决API权限问题
  • 配置合法域名白名单
  • 提交微信小程序审核时的地图相关注意事项

更多功能,查看官方文档添加相关控件https://uniapp.dcloud.net.cn/component/map.html#map

相关推荐
Jiaberrr7 小时前
解决uni-app通用上传与后端接口不匹配问题:原生上传文件方法封装 ✨
前端·javascript·uni-app
李慕婉学姐8 小时前
【开题答辩过程】以《基于微信小程序的线上讲座管理系统》为例,不会开题答辩的可以进来看看
javascript·mysql·微信小程序
2501_915918419 小时前
iOS 上架应用市场全流程指南,App Store 审核机制、证书管理与跨平台免 Mac 上传发布方案(含开心上架实战)
android·macos·ios·小程序·uni-app·cocoa·iphone
Mr.Aholic10 小时前
分享几个开源的系统,包括小程序、商城系统、二手交易等常见的系统、很容易进行二次开发 【可以参考学习】
微信小程序·小程序·毕业设计·课程设计
2501_9159090611 小时前
HTTPS 错误排查实战,从握手到应用层的工程化流程
网络协议·http·ios·小程序·https·uni-app·iphone
JIngJaneIL16 小时前
口腔健康系统|口腔医疗|基于java和小程序的口腔健康系统小程序设计与实现(源码+数据库+文档)
java·数据库·spring boot·小程序·论文·毕设·口腔医疗小程序
小光学长1 天前
基于微信小程序的背单词系统x1o5sz72(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·微信小程序·小程序
晨旭缘1 天前
解决小程序样式隔离styleIsolation
小程序
开发加微信:hedian1161 天前
“十五五”规划前瞻:短剧小程序系统开发的技术浪潮与开发新机遇
微信·小程序