前提:
问题:
在项目中原本想直接使用uni.chooseLocation直接实现选择位置功能,但是在打包发版后发现它的搜索周围的功能用不了,就出现下面的情况:

解决方案:
后面查文档发现:

要想用它的功能,得开它的云服务一些杂七杂八的,本人觉得太麻烦,决定直接手搓一个!
本功能的目标是让用户通过拖拽地图的方式选择目标位置,并获取该位置的详细信息(如地址、经纬度),最终将这些数据传递给上层页面进行进一步处理。整个流程涉及父子组件通信、高德地图 API 调用以及异步数据交互等多个关键技术点。
实现过程:
组成:
- 父组件:
poiMap.vue- 主页面,负责展示地图和确认按钮。
- 接收子组件传递的位置数据并跳转至上层页面。
- 子组件:
poiBox.vue- 封装了高德地图的核心逻辑。
- 使用
renderjs模块调用高德地图 SDK 实现地图渲染和位置选择。
- 依赖库
- 高德地图 JavaScript API(
@amap/amap-jsapi-loader) - 高德地图 UI 组件库(
AMapUI.PositionPicker)
- 高德地图 JavaScript API(
实现步骤:
1. 父组件逻辑(poiMap.vue)
数据传递与接收
父组件通过 props 向子组件传递初始经纬度数据:
javascript
onLoad(option) { this.allProps = [option.longitude, option.latitude]; }
同时,通过 $emit 监听子组件传递回来的位置数据:
javascript
handleCompleteAdd(data) { this.position = data; }
页面跳转
用户点击"确认"按钮后,将选中的位置数据通过 URL 参数传递至上层页面:
javascript
handleMap() {
uni.redirectTo({
url: `/pages/addFarm/addFarm?position=${JSON.stringify(this.position)}`
});
}
2. 子组件逻辑(poiBox.vue)
地图初始化
使用 AMapLoader 动态加载高德地图 SDK 并创建地图实例:
javascript
initAMap() {
AMapLoader.load({
key: "your-api-key",
version: "1.4.15",
plugins: ["AMap.Geolocation", "misc/PositionPicker"]
}).then((AMap) => {
map = new AMap.Map("container", {
zoom: 14,
center: currentLngLat
});
});
}
位置选择器集成
通过 AMapUI.PositionPicker 插件实现拖拽选择位置的功能:
javascript
AMapUI.loadUI(['misc/PositionPicker'], (PositionPicker) => {
positionPicker = new PositionPicker({
mode: 'dragMap',
map: map
});
positionPicker.on('success', (positionResult) => {
const geolocation = {
address: positionResult.address,
position: positionResult.position
};
this.$ownerInstance.callMethod("handlePositionData", geolocation);
});
});
数据回传
将选中的位置数据通过 $ownerInstance.callMethod 回传给逻辑层:
javascript
handlePositionData(data) {
this.position = data;
this.$emit('completeAdd', data);
}
3. 异步加载插件
由于 AMapUI.PositionPicker 不属于基础插件,需通过动态脚本加载:
javascript
const script = document.createElement('script');
script.src = 'https://webapi.amap.com/ui/1.1/main.js?v=1.1.1';
document.head.appendChild(script);
4. 地图事件监听
通过 positionPicker.on('success') 监听用户拖拽完成后的位置信息,并实时更新界面内容。
实现效果:
