原因:
uniapp
可以通过uni.getLocation
获取用户定位,但是获取到的定位没有中文地址,所以我们需要通过第三方SDK
例如高德地图或者腾讯地图来获取中文定位信息。
去腾讯地图开发者平台:《传送地址》
进入小程序之后,询问用户是否同意授权位置信息:
同意之后:
储存的数据(其实还有很多,只不过是取了需要的部分储存下来):
这里是封装成了组件,因为在很多地方都有用到:
<template>
<view>
// 使用 uniapp 的 picker 内置组件供用户手动选择定位
// u-icon 是 uview 组件库的图标组件
<picker mode="region" @change="handlePosition">
<view class="search-map">
<u-icon name="map" size="23" color="#fff"></u-icon>
<text class="search-text">{{position || '地区'}}</text>
</view>
</picker>
</view>
</template>
<script>
/**
* 引入腾讯地图微信小程序SDK
*/
import QQMapWX from '@/utils/map/qqmap-wx-jssdk.js'
export default {
name:"location",
mounted() {
// 进入小程序调用授权接口,获取用户当前定位
if (!uni.getStorageSync('located')) this.getLocation()
},
data() {
return {
locationInfo: {}, // 用于存储获取得到的数据
position: uni.getStorageSync('location').district // 这里想要渲染省还是市还是区的数据都可以,看你业务需求
};
},
methods: {
/**
* 向父组件传递数据
* */
toParent() {
this.$emit('watchPosition', {data: this.locationInfo})
},
/**
* 用户手动选择定位
* @e picker获取得到的参数
* */
handlePosition(e) {
this.position = e.detail.value[2]
this.locationInfo.province = e.detail.value[0]
this.locationInfo.city = e.detail.value[1]
this.locationInfo.district = e.detail.value[2]
this.mapBack(e.detail.value[0], e.detail.value[1])
this.toParent()
},
/**
* 获取用户当前定位
*/
getLocation() {
let that = this
// 向用户发起授权请求,弹框提示
uni.authorize({
// 获取用户定位信息
scope: "scope.userLocation",
// 用户同意授权执行
success() {
// 引入腾讯地图API,实例化核心类
let qqMapSdk = new QQMapWX({
// 填入你上面申请的应用key值
key: '你的key值'
})
// 获取位置信息
uni.getLocation({
type: 'wgs84',
success(result) {
// 逆地址解析方法
qqMapSdk.reverseGeocoder({
location: {
latitude: result.latitude,
longitude: result.longitude
},
success(res) {
that.position = res.result.ad_info.district
that.locationInfo.province = res.result.ad_info.province
that.locationInfo.city = res.result.ad_info.city
that.locationInfo.district = res.result.ad_info.district
that.mapBack(res.result.ad_info.province, res.result.ad_info.city)
},
fail(err) {
console.log('逆地址解析失败');
}
})
}
})
},
fail(err) {
uni.showToast({
icon: 'none',
title: '注意:需要授权获取定位,否则部分功能将无法使用',
duration: 2000
})
}
})
},
/**
* 转换为后端的定位编码
* @province 需要转换编码的省份
* @city 需要转换编码的城市
* */
mapBack(province, city) {
let that = this
const localLocation = JSON.parse(uni.getStorageSync('address'))
localLocation.map(item => {
if (item.name == province.substr(0, province.length - 1)) {
that.locationInfo.province_code = ''
that.locationInfo.city_code = item.id
} else {
item.address.map(items => {
if (items.name == city.substr(0, city.length - 1)) {
that.locationInfo.province_code = item.id
that.locationInfo.city_code = items.id
}
})
}
})
// 本地保存定位
uni.setStorageSync('location', that.locationInfo)
// 更新全局定位数据
uni.setStorageSync('located', true)
}
}
}
</script>
<style scoped lang="scss">
.search-map {
display: flex;
justify-content: center;
align-items: center;
color: white;
.search-text {
color:#fff;
font-size: 24rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
</style>
自动获取或者是手动获取定位,组件内都会自动渲染获取的地点,不用监听:
<search @inputValue="bindinput" @confirm="bindConfirm">
<location @watchPosition="watchComPosition" slot="left"></location> // 自动渲染定位
<picker slot="center" mode="selector" :range="selectArray" @change="bindSelect">
<view class="search-drop row-c">
<view class="search-drop-text">{{select == 0 ? '我要买' : '我要卖'}}</view>
<u-icon color="#fff" name="arrow-down"></u-icon>
</view>
</picker>
<view slot="right" @click="$u.throttle(bindSearch, 3000)" class="row-c">
<u-icon color="#fff" size="27" name="search"></u-icon>
</view>
</search>
想要用本地储存的定位数据(uni.getStorageSync('location')
)来获取某个地区的商品数据:
async filter() {
let that = this
// 取消全部已收藏状态
this.isSubAll = false
// 获取本地储存的定位数据
const cityCode = uni.getStorageSync('location')
const handleObj = {
city: cityCode.city_code ? cityCode.city_code : cityCode.province_code,
cate: that.selected,
pay_content: that.search,
time: that.dateNum,
delivery: that.packNum,
selltype: that.typeNum,
page: that.page,
pagesize: that.pageSize,
user_id: uni.getStorageSync('userinfo').user_id
}
await purchase(handleObj).then((res) => {
if (res.statusCode == 200) {
that.loadingStatus = 'loadmore'
that.lastPage = res.data.page_info.last_page
that.total = res.data.page_info.total
const resultArray = res.data.data
// 如果有数据
if (resultArray.length != 0) {
// 如果是下拉加载,则叠加数据,否则,直接赋值
if (that.pageFlag) {
that.pageFlag = false
that.buyListData = [...that.buyListData, ...resultArray]
} else {
that.buyListData = [...resultArray]
}
// 数据赋值->深拷贝,并刨除已收藏商品
that.cacheArray = JSON.parse(JSON.stringify(that.buyListData))
} else {
// 如果没有数据,也不是下拉加载,直接赋值为空
if (!that.pageFlag) {
that.buyListData = []
that.cacheArray = []
}
}
}
})
}
如果用户通过手动选择定位,来获取某个地区的商品数据,则可以通过组件内实现封装好的方法来监听获取的数据和变化:
// 监听子组件手动定位事件
watchComPosition() {
this.page = 1
this.filter()
}