超详细小程序定位地图模块全系列开发教学

前言:如果想最大化吸取本文经验,须有小程序开发基础,本文细节比较多(多看注释的提醒内容),请耐心理解,多动手尝试,收获会更加丰富

1.定位系统使用场景及概述

如美团外卖小程序

点定位

点搜索

显而易见,随便一个电商小程序都需要用到定位服务,那么今天我们做一个类似的定位模块
定位模块总览
外部页面

内部页面(下文说的内外部页面就是指这两个)

好了接下来我们开始动手

2.定位外部模块样式

效果

代码

//wxml
<view bindtap="getLocation" class="location">
 <image src="../../img/location.png"></image>
 <view>{{location}}</view>
</view>
//wxss
.location{
 font-size: 17px;
 width: 100%;
 background:rgb(196, 228, 123);
 display: flex;
 /* 对于两个块元素 */
 /* 垂直居中 */
 align-items: center;
 /* 水平居中 */
 justify-content: center;
}
.location image{
 width: 23px;
 height: 23px;
}

先不用管上面的{{location}},它是我们之后要从全局变量传过来的位置信息,定位符号是用image图片放进去的,我们用flex布局让图片和文字在同一行居中显示(见注释)

3.定位模块内部样式

效果

代码(分五个小模块,见注释)

//wxml
//搜索模块
<view class="header">
 <view class="search">
<image src="../../img/sousuo.png"></image>
 </view>
 <view class="input">
<input type="text" placeholder=" 请输入你想要的内容" placeholder-class="placeholder" bindinput="bindInput" bindfocus="bindFocus" auto-focus="{{autoFocus}}"></input>
 </view>
</view>
//定位模块
<view class="dw">
<button size="mini" bindtap="getCity">
 <image src='../../img/location.png'></image>
 <text>定位</text>
 </button>
</view>
//当前位置模块
<view >当前所在位置</view>
<button size="mini" bindtap="nowCity" class='nowcity'>{{city}}</button>
//热门城市模块
<view class="hotcity">热门城市</view>
<view wx:for="{{hotcity}}" wx:key='index' class="hotcity1">
 <!-- 用了view循环之后要把view设置为inline元素,不然5个view会分成5行显示 -->
<button size="mini" bindtap="hotCity" data-hotcityindex='{{index}}'>{{item.cityName}}</button>
</view>
//地图模块
<view class="map">
<map longitude="{{longitude}}" latitude="{{latitude}}" scale="14"></map>
</view>

由于我的搜索框是用了自定义组件里面的搜索组件,我是在组件的基础上改出来的,原组件是这样的

我们需要把搜索图标隐藏,我们直接设置它的透明度为0,然后把我们的定位文字跟图标通过定位直接定位到搜索框的左边,所以样式的代码如下(代码太多不好找的话可以Ctrl+F直接搜索)

//wxss
.dw{
 color:rgb(0, 0, 0);
 position: absolute;
 top: 14px;
 left: -2px;
}
.dw button{
 background: white;
 padding-right: 0;
 display: flex;
 align-items: center;
 font-weight: 600 !important;
}
.nowcity{
 font-weight: normal;
}
.dw image{
 width: 23px;
 height: 23px;
}
page{
 padding: 10px;
}
.hotcity1 button{
 margin: 10px;
 margin-bottom: 0;
 font-weight: 500 !important;
  border-radius: 10px !important;
}
.hotcity{
 margin-top: 6px;

}
.map_container{
 position: absolute;
 top: 0;
 bottom: 0;
 left: 0;
 right: 0;
}
.header{
 display: flex;
}
.search{
flex:1;
height: 40px;
text-align: center;
background: #fff;
}
.input{
 flex:9;
 height: 40px;
 background: #fff;
}
.input input{
 background: #f1f1f1;
height: 30px;
margin-top: 5px;
margin-bottom: 5px;
margin-right: 8px;
border-radius: 10px;
}
.search image{
 width: 70%;
 height: 25px;
 padding-top: 9px;
 padding-left: 5px;
}
.placeholder{
 font-size: 14px;
}
.search image{
 opacity: 0;
}
.input{
 flex:4;
}
.input input{
position: relative;
right: 0px;
}
.hotcity1{
 display: inline;
}
.map{
 position: relative;
}
map{
 border:5px solid green;
 text-align: center;
 margin: 10px auto;
position: relative;
right: 10px;
 width: 90%;
 height: 150px;
}

然后我们的搜索里面点击搜索还会跳转到新的搜索页面,效果如下

这里我们可以直接复用上面的搜索组件,样式代码就不再贴出来了,这个模块要将搜索自动匹配的地点名称用循环的方式显示出来,代码如下

//wxml
<import src="../templates/search/search" />
<template is="search"></template>
<view bindtouchstart="bindSearch" data-keywords="{{i.name}}"
 class="text_box" wx:for="{{tips}}" wx:for-item="i" wx:key='index'>
 {{i.name}}
</view>
//wxss
@import '../templates/search/search.wxss';
.text_box{
 margin: 10px 25px;
 border-bottom:1px solid #c3c3c3;
 padding-bottom:10px
}

4.外部跳转

当我们点击外部的位置信息,就跳转到内部的定位模块,刚刚我们在上面给外部的标签设置了触摸事件getLocation,接下来只要到js里面设置点击跳转(navigateTo)就可以了,但由于我们的位置信息是用全局变量赋值的,所以我们要在app.js设置一个全局变量,代码如下

//app.js
App({
 globalData: {
  city:'暂未定位',
  userInfo:'无'
 },
 )}
//外部js
// 引入app.js
const app=getApp()
const appG=app.globalData
 data: {
//这里要初始化location,并将全局变量赋值给它
aboutList:'',
location:appG.city
 },
 Page({
 //定义触摸事件
 getLocation(){
 wx.navigateTo({
 //跳转到内部定位页面
  url: '../location/location',
 })
},
)}

5.点击定位

做这个功能之前我们需要先考虑用什么地图接口,常用的有百度地图,腾讯地图,高德地图,本文选用高德地图接口作为演示,搜索https://lbs.amap.com/,注册,进入控制台,创建新应用,

再添加key

这个key就像我们小程序调用接口时的验证码,有了它我们才能从高德调取位置的数据,然后我们点击key后面的设置,再点击微信小程序SDK

进去之后点这两个,下载amap-wx.js 文件,然后在你的小程序目录里面创建一个libs文件,把这个amap-wx.js扔进去

接下来我们来到内部定位页面的js文件,因为这里要对全局变量进行修改来达到修改页面数据的效果,所以也要引入app.js,并把全局变量初始化到data里面,除此之外我们要引入高德的文件来实现高德接口的调用,在data里面我们这里顺便把等会要用到的热门城市等数据一并初始化了

const app=getApp()
const appG=app.globalData
//key里面填高德控制台里面给你的key
const myAmapFun = new amapFile.AMapWX({key:'xxxxxxxxxx'});
 data: {
city:appG.city,
hotcity:[
 {'cityName':'北京市',longitude:'116.395645038',latitude:'39.9299857781'},
 {'cityName':'上海市',longitude:'121.487899486',latitude:'31.24916171'},
 {'cityName':'广州市',longitude:'113.307649675',latitude:'23.1200491021'},
 {'cityName':'深圳市',longitude:'114.025973657',latitude:'22.5460535462'},
 {'cityName':'武汉市',longitude:'114.316200103',latitude:'30.5810841269'},
],
tips: {},//搜索自动匹配的内容
longitude:'116.4',//经度(初始值在北京)
latitude:'39.9'//纬度(初始值在北京)
}

然后我们给定位按钮设置点击事件getCity,这里用到高德地图里面的获取地址描述数据方法,教程可以参考刚刚高德控制台微信SDK里面的教程(下面搜索自动匹配提示的教程也一样)

此外我们我们还要在小程序后台给高德的接口添加域名,操作步骤为
登录微信公众平台,“设置“–>"开发设置"设置request合法域名,将https://restapi.amap.com 中添加进去,这样我们才能请求到高德的数据

代码

getCity(){
 myAmapFun.getRegeo({
  success: data=>{
   // that.setData({
   //  city:data[0].desc.slice(0,2)
   // })
   appG.city=data[0].desc
   wx.getLocation({
    success:res=>{
this.setData({
  latitude:res.latitude,
  longitude:res.longitude
})
wx.setStorageSync('city', appG.city)
wx.setStorageSync('latitude', res.latitude)
wx.setStorageSync('longitude', res.longitude)
    }
   })
  },
  fail: function(info){
   //失败回调
   console.log(info)
  }
 })
},

getRegeo方法的成功回调函数里的参数包含了定位后的位置信息(可以自己输出一下),我们把它赋值给全局变量,然后再用setData再次把全局变量appG.city赋值给data里面的city(因为appG.city已经改变了,要重新赋值页面才会更新),除此之外我们还要把获取到的位置信息同步缓存起来,下次进入页面的时候在onLoad里面先判断有没有缓存的数据,如果有就直接使用缓存的数据,没有就用默认值,代码如下

onLoad: function (options) {
  // 进页面先看有无缓存数据,如果没有再读默认值,onLoad里面可以取到this.data
  const latitude=wx.getStorageSync('latitude')
  const longitude=wx.getStorageSync('longitude')
  const city=wx.getStorageSync('city')
  //用了三目运算符,不习惯也可以使用if
  latitude&&longitude&&city?
  this.setData({
   latitude:latitude,
   longitude:longitude
  }):false
 },

6.未定位时弹出定位框

给当前位置标签添加点击事件,判断当位置信息为初始值暂未定位时,弹出是否定位的选择框,当用户点击确定时,执行一次getCity函数即可,效果如下

代码

nowCity(){
 if(this.data.city!='暂未定位'){
  wx.switchTab({
   url: '../about/about',
  })
 }else{
  wx.showModal({
   title: '暂未定位',
   content: '现在要进行定位吗',
   success: (res)=>{
    if (res.confirm) {
     this.getCity()
    } else if (res.cancel) {
     return false
    }
   }
  })
 }
},

7.热门城市点击跳转,更新数据

当我们点击热门城市里面的按钮时,跳转到外部页面,并且把对应热门城市名称更新到全局的city来传到外部页面显示,同时还要更新全局中的经纬度数据,对于经纬度只要更新缓存即可,下一次进入内部定位页面时再判断缓存中有无定位数据,如果有就直接用,city数据是更新+缓存,代码如下

hotCity(e){
 const index=e.currentTarget.dataset.hotcityindex
 //更新
 appG.city=this.data.hotcity[index].cityName
 //缓存
  wx.setStorageSync('city', appG.city)
 wx.setStorageSync('latitude', this.data.hotcity[index].latitude)
 wx.setStorageSync('longitude', this.data.hotcity[index].longitude)
 //跳转
wx.reLaunch({
 url: '../about/about',
 success:()=>{
  // 不要把数据的更新写在这里,要在跳转之前就写好,因为这个回调函数是在跳转的页面所有函数
  // 执行完之后才执行的,会导致数据两次跳转次才更新
 }
})
},

上述代码中注意要在热门城市的循环标签用data-hotcityindex="{{index}}"把下标传到js中,再在js中用e.currentTarget.dataset.hotcityindex去取出来用,这个下标用来对应热门城市数组的每一个对象,这样我们就可以用this.data.hotcity[index].cityName来获取被点击的城市的名称,再把它更新到appG.city中,注意跳转的时候不能用wx.switchTab,因为从外部页面进来的时候已经打开了外部页面,那么用wx.switchTab的时候只会执行外部页面的onShow函数,而不会执行onLoad,会导致页面数据无法更新

8.搜索跳转和输入自动匹配地名

搜索跳转新页面(给内部定位页面设置聚焦事件)

bindFocus(e){
 wx.navigateTo({
  url: '../locationSearch/locationSearch',
 })
},

注意内部页面的搜索框不是自动聚焦的,而跳转到新的搜索页面的搜索框是会自动聚焦的,这一点我们可以通过在搜索组件的input标签添加auto-focus="{{autoFocus}}",再控制autoFocus的值来控制是否自动聚焦,代码如下

<template is="search" data="{{autoFocus}}"></template>

注意data="{{xxx}}"是自定义组件特有的传参方式,可以把js里面的值传到组件中使用不过我们得先在搜索页面的js的data中给autoFocus赋值,这里顺便把保存自动匹配的地名的值tips也初始化了

data: {
autoFocus:true,
tips:{}
 },

接下来我们写输入自动匹配地名,同样在搜索页面的js引入全局变量和高德js文件

const amapFile = require('../../libs/amap-wx.js');
const app=getApp()
const appG=app.globalData
const myAmapFun = new amapFile.AMapWX({key:'0c2c8f2007702caa7e0498d6ad072f83'});

然后我们来监听用户的输入行为,设置为bindInput函数

<input type="text" placeholder=" 请输入你想要的内容" placeholder-class="placeholder"
 bindinput="bindInput" bindfocus="bindFocus" auto-focus="{{autoFocus}}"></input>

搜索页面的js中定义bindInput

bindInput(e){
 myAmapFun.getInputtips({
  // keywords为必填,不然无法获得tips,也就不会进入success函数
  keywords:e.detail.value,
  success:data=>{
 this.setData({
  tips:data.tips
 })
  }
 })
},

上面的getInputtips就是我们第5点中讲到的微信小程序SDK中的获取提示词里面的方法,可以自己去看高德的教程,此处不再赘述,上面的keywords的值就是用户输入的内容,接口会根据这个去寻找对应匹配的地名并返回在success函数的参数中,我们只需要在成功回调函数中更新tips就可以了,那么此时假如我们输入武汉,效果如下

那么当我们点击自动匹配的地名的时候,需要返回到外部页面,并且更新数据,更新缓存,思路和上面的跳转方法是一样的,代码如下

bindSearch(e){
 const location=this.data.tips[e.currentTarget.dataset.searchindex]
 wx.setStorageSync('city', location.name)
 if(location.location.length!=0){
  const longitude=location.location.split(',')[0]
  const latitude=location.location.split(',')[1]
 wx.setStorageSync('latitude', latitude)
 wx.setStorageSync('longitude', longitude)
 wx.reLaunch({
  url: '../about/about',
   success:()=>{
       appG.city=e.currentTarget.dataset.keywords
  }
 })
 }else{
  wx.reLaunch({
   url: '../about/about',
    success:()=>{
        appG.city=e.currentTarget.dataset.keywords
        setTimeout(()=>{wx.showToast({
         title: '暂无经纬度数据',
        // 提示延迟时间,不能用字符串
         duration:2000,
         icon:'none'
        })
       },500);
   }
  })
 }

由于不是每一个自动匹配的地点都有经纬度,所以我们对没有经纬度的地名做业务退步处理,仅提醒暂无经纬度的数据,(有时候业务退一小步,技术就有一大步的发挥空间–《大型网站技术架构》——李智慧),细心的你们肯定注意到上面用了定时器,因为如果不使用定时器,这个弹框是不会显示出来的,这个函数在页面加载完成之前就已经执行了,所以我们给他来一个定时器作为异步函数延迟执行,才能有弹框

9.对整个模块的优化和思考

对上述代码,笔者开发完之后发现了如下问题:
代码冗余严重,主要表现在多次使用缓存的api,重复量的地方很多
整个模块内部互相调用复杂,高耦合,低拓展
某些地方把简单的逻辑复杂化了,代码不够整洁
对于上述问题,笔者有如下思考:
通过封装缓存api来减少不必要的代码量,提高代码整洁度
对整个模块重新构思,提高可拓展性和可复用性(由于笔者水平有限,暂时搁置)
模块从开发开始到开发完成需要不断的演化和改进,这个过程才是让开发者成长的关键

到此这篇关于超详细小程序定位地图模块全系列开发教学 的文章就介绍到这了,更多相关小程序定位地图内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 超详细小程序定位地图模块全系列开发教学

    前言:如果想最大化吸取本文经验,须有小程序开发基础,本文细节比较多(多看注释的提醒内容),请耐心理解,多动手尝试,收获会更加丰富 1.定位系统使用场景及概述 如美团外卖小程序 点定位 点搜索 显而易见,随便一个电商小程序都需要用到定位服务,那么今天我们做一个类似的定位模块 定位模块总览 外部页面 内部页面(下文说的内外部页面就是指这两个) 好了接下来我们开始动手 2.定位外部模块样式 效果 代码 //wxml <view bindtap="getLocation" class=&

  • 微信小程序 定位到当前城市实现实例代码

    微信小程序 定位到当前城市 首先需要申请百度地图Geocoding API Geocoding API包括地址解析和逆地址解析功能: 1.地理编码:即地址解析,由详细到街道的结构化地址得到百度经纬度信息,例如:"北京市海淀区中关村南大街27号"地址解析的结果是"lng:116.31985,lat:39.959836".同时,地理编码也支持名胜古迹.标志性建筑名称直接解析返回百度经纬度,例如:"百度大厦"地址解析的结果是"lng:116.

  • 微信小程序 高德地图SDK详解及简单实例(源码下载)

    微信小程序 高德地图SDK: 简介 微信小程序 SDK 帮您在微信小程序中获取高德丰富的地址描述.POI和实时天气数据. 功能介绍 账号与Key的申请 注册成为高德开发者需要分三步: 第一步,注册高德开发者:第二步,去控制台创建应用:第三步,获取Key. 1注册高德开发者 2创建应用 3获取API key 获取API Key 入门指南 最后更新时间: 2017年1月9日 本指南是使用微信小程序SDK的快速入门指南. 第 1 步:下载并安装微信小程序开发工具 按照微信小程序开发文档下载并安装微信小

  • 微信小程序 wxapp地图 map详解

    微信小程序 wxapp地图 map: map 属性名 类型 默认值 说明 longitude Number   中心经度 latitude Number   中心纬度 scale Number 1 缩放级别 markers Array   标记点 covers Array   覆盖物 标记点 标记点用于在地图上显示标记的位置,不能自定义图标和样式 属性 说明 类型 必填 备注 latitude 纬度 Number 是 浮点数,范围 -90 ~ 90 longitude 经度 Number 是 浮

  • 微信小程序在地图选择地址并返回经纬度简单示例

    本文实例讲述了微信小程序在地图选择地址并返回经纬度功能.分享给大家供大家参考,具体如下: 微信小程序的地址管理中,经常需要获取地址的详细地址信息和地址经纬度信息 wxml文件部分代码: <button bindtap="mapView" style="margin:10px">查看地图</button> js文件主要功能代码: mapView:function(){ var that = this wx.chooseLocation({ su

  • 微信小程序定位当前城市的方法

    微信小程序定位获取当前所在城市,供大家参考,具体内容如下 1.利用微信小程序接口 wx.getLocation() 获取当前经纬度,接口. 2.拿到经纬度之后,通过微信的wx.request()请求百度地图的解析接口,传入我们获取到的经纬度,拿到当前定位的城市. Page({ data: { city: '' }, onLoad: function (options) { this.loadInfo(); }, loadInfo: function () { var page = this wx

  • Python实战小程序利用matplotlib模块画图代码分享

    Python中的数据可视化 matplotlib 是python最著名的绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地进行制图.而且也可以方便地将它作为绘图控件. 实战小程序:画出y=x^3的散点图 样例代码如下: #coding=utf-8 import pylab as y #引入pylab模块 x = y.np.linspace(-10, 10, 100) #设置x横坐标范围和点数 y.plot(x, x*x*x,'or') #生成图像 ax = y.gca() a

  • 微信小程序map地图使用方法详解

    本文实例为大家分享了微信小程序map地图使用的具体实现代码,供大家参考,具体内容如下 以下代码是主要的代码片段 <!-- 地图部分 --> <!-- enable-traffic 显示路况 --> <view class="map_container"> <map id='customerMap' class="map" :longitude='longitude' :latitude='latitude' :scale='

  • uni-app 开发微信小程序定位功能

    目录 一.注册账号 二.创建应用和Key 1.进入控制台 2.创建应用 3.创建Key 三.登录微信公众平台后台 四.下载微信小程序JavaScriptSDK 五.代码实现 六.一般获取经纬度地址 七.相对精确的获取经纬度地址 1.获取位置监听的权限 2.开启位置监听 3.监听实时地理位置变化 使用onLocationChange方法持续监听地址,根据定位精度字段判断是否使用此次定位的经纬度. 已经会定位的直接跳七.相对精确的获取经纬度地址 一.注册账号 把信息都输入就好了 腾讯位置服务 - 立

  • 微信小程序网络请求模块封装的具体实现

    目录 前言 具体实现 1.确定结构 2.service网络请求的基本配置和公共方法 3.apis创建对应功能模块的网络请求方法 4.使用 总结 前言 在进行一个微信小程序项目开发的时候我需要网络请求模块和后端数据进行沟通: 接下来就和我一起简单的封装的一下网络请求模块吧. 具体实现 1. 确定结构 在根目录新建 service和apis文件夹: service用来做网络请求的基本配置和输出公共的网络请求方法: apis用来创建对应功能模块的网络请求方法(ex:操作音乐.操作视频): 2. ser

随机推荐