1.首先先写页面结构
<template>
<view class="map_wrap">
<map id="mapSelected" style="width: 690rpx; height: 300px; margin-left: 30rpx;" :latitude="latitude" :longitude="longitude" :markers="covers" :controls="controls" :scale="18" @controltap="controltap" @tap="clickMap"
@regionchange="regionchange">
</map>
<view class="tips_text" style="margin-top: 30rpx; padding: 0 30rpx; font-size: 30rpx; box-sizing: border-box;">
<view class="tips_header">当前地址:</view>
<view class="address_text">{{address}}</view>
<view class="tips_header">推荐地址:</view>
<view class="address_text">{{address_info}}</view>
</view>
<!-- 保存按钮 -->
<view class="add_address_wrap">
<view class="add_address_btn" @click="saveAddress">保存</view>
</view>
</view>
</template>
latitude::经度
longitude:纬度
markers:数组类型,标记点,用于标记你目前所处的位置。另外它还有很多属性,链接:map组件官方文档
scale:缩放级别,取值范围为5-18,默认16
controls:控件,可让你手指拖动地图时,它在你指定的位置不动
regionchange:视野发生变化时触发的事件,依据这个函数的回调参数和控件来实时获取你选择的地址
2.属性事件介绍完了,话不多说,开始撸代码逻辑。毕竟实践是获取知识最好的途径。在微信小程序中获取用户的当前地理位置是需要用户手动授权的。
isGetLocation(a = "scope.userLocation") { // 3. 检查当前是否已经授权访问scope属性
var _this = this;
uni.getSetting({
success(res) {
console.log(res)
if (!res.authSetting[a]) { // 3.1 每次进入程序判断当前是否获得授权,如果没有就去获得授权,如果获得授权,就直接获取当前地理位置
_this.getAuthorizeInfo()
} else {
_this.getLocationInfo()
}
}
});
}
使用uni.getSetting()方法来获取用户的当前设置,每次进入程序判断当前是否获得授权,如果没有,就去调起弹窗请求获得授权,如果获得授权,就直接获取当前地理位置。
getAuthorizeInfo(a = "scope.userLocation") { // 1. uniapp弹窗弹出获取授权(地理,个人微信信息等授权信息)弹窗
var _this = this;
uni.authorize({
scope: a,
success() { //1.1 允许授权
_this.getLocationInfo();
}
})
}
uni.authorize()调用后会立刻弹窗询问用户是否同意授权小程序使用某项功能或获取用户的某些数据,但不会实际调用对应接口,等用户点击确定之后才会调用对应接口。如果用户之前已经同意授权,则不会出现弹窗,直接返回成功。如果用户之前拒绝了授权,此接口会直接进入失败回调。注意:此时选择不同的接口有不同的适用场景,萝卜青菜,各有所爱。
2.1 如果选择的是uni.chooseLocation(),这个简单,直接调用即可。
getLocationInfo () {
uni.chooseLocation({
success: (res) => {
console.log(res)
this.addressInfoText = res.name
}
})
}
选择地址点击确定以后返回数据,此时可根据需要选择你的收货地址。
2.1 如果选择的是uni.getLocation(),这个相对来说复杂一点。
(1)先去获取当前所在位置的经纬度
uni.getLocation({
type: 'gcj02',
success: (res) => {
console.log(res)
this.latitude = res.latitude.toString()
this.longitude = res.longitude.toString()
// 获取地理位置详情信息
this.getLocationDetail()
}
});
(2)然后根据经纬度获取详细的地址
getLocationDetail () {
uni.request({
header: {
"Content-Type": "application/text"
},
url: 'https://apis.map.qq.com/ws/geocoder/v1/?location=' + this.latitude + ',' + this.longitude +
'&key=XOXBZ-MZWWD-CDX4H-PONXN-UA5PJ-D7FJN',
success:(re)=> {
//成功获取到经纬度
console.log(re)
if (re.statusCode == 200) {
this.address_info_recomd = re.data.result.formatted_addresses.recommend
this.address_info = re.data.result.address_reference.town.title + re.data.result.address_reference.street.title + re.data.result.address_reference.landmark_l2.title
this.address = re.data.result.address
} else {
uni.showToast({
title: '获取地理位置失败,请重试',
icon: "none"
})
}
}
});
}
(3)再把控件定在地图的中心点,然后手动拖动地图,从而实现手动选择收货地址的功能。
data () {
return {
city: '', // 城市
address_info: '', // 详细地址
address: '', // 总地址
latitude: 39.909, // 默认经度(北京天安门)
longitude: 116.39742, // 默认纬度
covers: [{
latitude: 39.909, // 定位图标所在的位置(北京天安门)
longitude: 116.39742,
// iconPath: '../../../../../static/uploads/image/profile/location_address.png' // 默认自带图标,可自定义图标
}],
controls: [{ // 控件
id: 99,
position: { // 控件位置
left: 160,
top: 120
},
iconPath: '../../../../../static/uploads/image/profile/location_address.png' // 控件图标
}]
}
}
// 在地图渲染更新完成时触发
regionchange (e) {
console.log(e)
if (e.type == 'end' && (e.causedBy == 'scale' || e.causedBy == 'drag')) {
this.mapCtx = uni.createMapContext("mapSelected"); // 创建map的上下文对象, 从而操控map组件
this.mapCtx.getCenterLocation({
success: (res) => {
console.log(res)
this.latitude = res.latitude
this.longitude = res.longitude
this.getLocationDetail()
}
})
}
}
mapSelected:map组件的id,结合以上方法去实时获取你选择位置的经纬度,根据经纬度即可实现实时选择收货地址的功能。
可能会踩的坑
这个在app.json中一定要配置好
"permission": {
"scope.userLocation": {
"desc": "你的位置信息将用于小程序位置接口的效果展示"
}
}
也可在manifest.json这里配置,选择微信小程序配置,勾选位置接口,如下图
另外服务端口号也要开启