uniapp使用vue3和ts开发小程序获取用户城市定位

这个组件的功能:可以重新定位获取到用户的具体位置,这个是通过getLocation这个api和高德地图的api获取到的,getLocation这个api需要在微信公众平台后台>开发管理> 接口管理里面申请才能使用的,不然无法使用哦,这个接口申请好像特别难,需要技巧,希望大家都能申请到吧。高德的api需要到高德的后台获取,个人开发者每天有5000限额可以使用。

也可以通过点击右边的字母快速跳转到对应的城市,可以点击热门城市或者城市列表快速定位城市。 

选择城市页面展示: 

具体代码:

<template>
  <view class="main-Location">
    <!-- 字母区域 -->
    <view class="Location-Letter">
      <view hover-class="Click-Latter" @tap="getLetter('ScrollTop')">*</view>
      <view v-for="(l, i) in LatterName" :key="i" hover-class="Click-Latter" @tap="getLetter(l)"
        :style="{ 'color': LetterId === l ? '#4662D9' : '#000' }">{
   
   { l }}</view>
    </view>

    <view class="ynq-AutoLocation u_flex jcsb">
      <view class="ynq-AutoAddress">
        <text class="ynq ynq-dizhi"></text>
        <text>当前定位:</text>
        <text>{
   
   { userStore.province }}</text>
      </view>

      <view class="ynq-ReLocation u_flex" @click="getLocationAuth">
        <u-icon name="reload" color="#000"></u-icon>
        <text class="ml5">重新定位</text>
      </view>
    </view>
    <scroll-view scroll-y="true" class="ynq-ScrollView" :scroll-into-view="LetterId">
      <!-- 热门城市 -->
      <view class="ynq-HotCity" id="ScrollTop">
        <view class="ynq-HotCityTitle">
          <text class="ynq ynq-fire"></text>
          <text>热门城市</text>
        </view>
        <view class="ynq-HotCityList flex">
          <text class="radius-3" @tap="setProvince(item)" v-for="(item, index) in HotCity" :key="index">{
   
   { item }}</text>
        </view>
      </view>
      <!-- 城市列表 -->
      <view class="ynq-CityList">
        <block v-for="(item, index) in cityList" :key="index">
          <view class="ynq-CityLetter" :id="item.initial">{
   
   { item.initial }}</view>
          <view class="ynq-CityLine">
            <text @tap="setProvince(item_city.name)" v-for="(item_city, name_index) in item.list" :key="name_index">{
   
   {
              item_city.name }}</text>
          </view>
        </block>
      </view>
    </scroll-view>
  </view>
</template>
 
<script setup lang="ts">
import { ref } from 'vue'
import cityList from './city'
import useUserStore from '@/store/user';

// 这里我使用了pinia来进行状态管理
const userStore = useUserStore();

let CityName = ref('北京')
const HotCity = ['北京', '深圳', '上海', '成都', '广州', '广东']
const LatterName = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
  'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
]
let LetterId = ref("")

// 右侧字母跳转到对应的城市
const getLetter = (name) => {
  LetterId.value = name
  console.log("点击名字", name);
  uni.pageScrollTo({
    selector: '#' + name,
    duration: 300
  })
}

// 点击城市名字存储
const setProvince = (Name) => {
  userStore.setUser("province", Name)
  CityName.value = Name
  //跳转返回
  uni.navigateBack()
}

// 根据API获取用户位置
const getLocationAuth = () => {
  // uni.choose
  uni.getSystemInfo({
    success(res) {
      console.log('getSystemInfo', res);
      let locationEnabled = res.locationEnabled; //判断手机定位服务是否开启
      let locationAuthorized = res.locationAuthorized; //判断定位服务是否允许微信授权
      if (locationEnabled == false || locationAuthorized == false) {
        //手机定位服务(GPS)未授权
        console.log('手机定位服务');
        uni.showModal({
          title: '提示',
          content: '请打开定位服务功能',
          showCancel: false, // 不显示取消按钮
          success: (res) => {
            console.log('showModalres', res);
          }
        })
      } else {
        console.log('uni.authorize');
        uni.getLocation({
          geocode: true, // 返回城市信息
          success: function (loction) {
            console.log("getLocation", loction);
            uni.request({
              url: 'https://restapi.amap.com/v3/geocode/regeo',
              method: 'GET',
              data: {
                key: '高德地图的key',
                location: loction.longitude + ',' + loction.latitude
              },
              success: (resda: any) => {
                console.log("resda", resda)
                const { province, district } = resda.data.regeocode.addressComponent
                CityName.value = province
                userStore.setUser("province", province)
                uni.navigateBack()
              }
            })
          }
        })
      }
    }
  })
}

</script>
 
<style lang="scss" scoped>
.main-Location {
  height: 100vh;
}

.ynq-AutoLocation {
  width: calc(100% - 40rpx);
  background: rgba(250, 250, 250, .5);
  padding: 20rpx 20rpx;

  text.ynq {
    font-size: 32rpx;
    margin-right: 10rpx;
  }

  text {
    font-size: 30rpx;
  }
}

.ynq-HotCity {
  padding: 20rpx;
}

.ynq-HotCityTitle {
  padding: 0rpx 0rpx;

  text.ynq {
    margin-right: 10rpx;
    color: #ff0000;
    font-size: 32rpx;
  }

  text {
    font-size: 30rpx;
  }
}

.ynq-HotCityList {
  padding: 20rpx 0 0 0;
  flex-wrap: wrap !important;

  text {
    width: 190rpx;
    display: inline-block;
    text-align: center;
    background: rgba(200, 200, 200, .2);
    font-size: 26rpx;
    margin: 10rpx;
    padding: 20rpx 10rpx;
  }
}

.Location-Letter {
  position: fixed;
  right: 5rpx;
  top: 180rpx;
  width: 30rpx;
  z-index: 100;

  view {
    display: block;
    width: 30rpx;
    text-align: center;
    height: 35rpx;
    line-height: 35rpx;
    font-size: 22rpx;
    transition: ease .3s;
    -webkit-transition: ease .3s;
  }
}

.ynq-CityList {
  padding: 0px 40rpx 0 20rpx;

  .ynq-CityLetter {
    line-height: 30rpx;
    height: 40rpx;
    font-size: 24rpx;
    border-bottom: 1px solid #f7f7f7;
    padding-left: 10rpx;
    color: #909090;
  }

  .ynq-CityLine {
    margin: 20rpx 0px;

    text {
      display: block;
      line-height: 60rpx;
      padding: 0px 10rpx;
      font-size: 30rpx;
      color: #767676;

      &:nth-child(even) {
        background-color: rgba(200, 200, 200, .12);
      }
    }
  }
}

.ynq-ScrollView {
  height: calc(100vh - 160rpx);
}

.Click-Latter {
  font-size: 30rpx !important;
}

.jcsb {
  justify-content: space-between;
}

.u_flex {
  display: flex;
  align-items: center;
}
</style>

猜你喜欢

转载自blog.csdn.net/weixin_44786530/article/details/134673903