注冊(cè)

微信小程序開發(fā)之OFO共享單車分析,小程序的地圖組件

2017-12-20
導(dǎo)讀:想學(xué)一下微信小程序,發(fā)現(xiàn)文檔這東西,干看真沒啥意思。所以打算自己先動(dòng)手?jǐn)]一個(gè)。摩拜單車有自己的小程序,基本功能都有,方便又小巧,甚是喜愛。于是我就萌生了一個(gè)給ofo共...
想學(xué)一下微信小程序,發(fā)現(xiàn)文檔這東西,干看真沒啥意思。所以打算自己先動(dòng)手?jǐn)]一個(gè)。摩拜單車有自己的小程序,基本功能都有,方便又小巧,甚是喜愛。于是我就萌生了一個(gè)給ofo共享單車擼一個(gè)小程序(不知道為啥ofo沒有小程序)的想法。
這一節(jié)我們先來剖析一下小程序的地圖組件

1.準(zhǔn)備工作

微信小程序當(dāng)然屬于騰訊大佬的(給大佬遞茶):微信小程序開發(fā)者工具下載,騰訊開放了小程序個(gè)人開發(fā)平臺(tái),只需要一個(gè)微信號(hào)就可以成為小程序開發(fā)者了。

2.小程序頁面

打開小程序開發(fā)者工具,用微信掃碼登錄,創(chuàng)建一個(gè)默認(rèn)的小程序。

pages文件夾下存放著小程序所有的業(yè)務(wù)頁面;
index文件夾就是一個(gè)頁面,index.wxml是頁面的結(jié)構(gòu)文件,類似html。
index.wxss是頁面的樣式,其實(shí)就是css;index.js是頁面的邏輯,數(shù)據(jù)請(qǐng)求與渲染都是都在這個(gè)頁面完成。
logs文件夾存放著小程序開發(fā)日志,目前暫時(shí)用不到。
utils.js可以編寫自己的JavaScript插件也可以引入第三方插件。
app.js處理全局的一些邏輯,比如定義全局變量存放獲取的用戶信息,這樣每個(gè)頁面都可以獲取用戶信息。
app.json 是全局配置文件,比如設(shè)置標(biāo)題欄的背景色等。
app.wxss 存放頁面的公共樣式,如果多個(gè)頁面需要用到同一樣式,就可以寫在這里。
調(diào)試按鈕用來進(jìn)行調(diào)試,功能和chrome dev調(diào)試工具差不多。
項(xiàng)目按鈕顯示預(yù)覽二維碼,用于真機(jī)調(diào)試。必須真機(jī)調(diào)試測(cè)試代碼,自帶的調(diào)試工具有時(shí)候會(huì)出bug

3.創(chuàng)建頁面結(jié)構(gòu)

上一節(jié)已經(jīng)分析了默認(rèn)的文件結(jié)構(gòu)以及它們的功能,現(xiàn)在我們要?jiǎng)?chuàng)建ofo小程序所需要的頁面。
刪除pages下默認(rèn)的index文件夾,logs/utils文件夾可選擇性刪除
在與pages同級(jí)目錄下創(chuàng)建images文件夾,存放頁面需要用到的圖標(biāo),下載圖標(biāo)
本小程序不需要在app.js里面編寫內(nèi)容,可以先注釋這里面的代碼
在app.json里,刪掉默認(rèn)代碼,編寫如下代碼(注:app.json文件里不能有任何注釋,這里是為了描述頁面功能更直觀):
  1. {
  2.   "pages":[
  3.     "pages/index/index", // 地圖頁
  4.     "pages/warn/index",  // 車輛報(bào)障頁
  5.     "pages/scanresult/index", // 掃碼成功頁
  6.     "pages/billing/index", // 開始計(jì)費(fèi)頁
  7.     "pages/my/index", // 賬戶頁
  8.     "pages/wallet/index", // 錢包頁
  9.     "pages/charge/index", // 充值頁
  10.     "pages/logs/logs" // 日志頁
  11.   ],
  12.   "window":{
  13.     "backgroundTextStyle":"light",
  14.     "navigationBarBackgroundColor": "#b9dd08", // 標(biāo)題欄背景色
  15.     "navigationBarTitleText": "ofo 共享單車",  // 標(biāo)題欄文字
  16.     "navigationBarTextStyle":"black" // 標(biāo)題欄文字樣式
  17.   }
  18. }
復(fù)制代碼

在app.wxss里面。我們先把頁面的通用樣式給出來(這一步我是在所有頁面寫完后,發(fā)現(xiàn)有些頁面有著相同的樣式,再把公共樣式抽離出來放在app.wxss里面的。)
  1. /**app.wxss**/
  2. .container{
  3.         background-color: #f2f2f2;
  4.         height: 100vh;
  5. }
  6. .title{
  7.         background-color: #f2f2f2;
  8.         padding: 30rpx 0 30rpx 50rpx;
  9.         font-size: 28rpx;
  10.         color: #000;
  11. }
  12. .tapbar{
  13.         display: flex;
  14.         align-items: center;
  15.         justify-content: space-between;
  16.         background-color: #fff;
  17.         padding: 40rpx;
  18. }
  19. .btn-charge{
  20.         width: 90%;
  21.         background-color: #b9dd08;
  22.         margin: 40rpx auto 30rpx;
  23.         text-align: center;
  24. }

保存后,你的pages文件夾下就是這樣的界面了(在app.json下創(chuàng)建路徑會(huì)自動(dòng)創(chuàng)建文件夾,賊方便):


4.編寫地圖首頁 (index文件夾)

先來看一下地圖首頁效果圖


頁面分析:
  • 整頁顯示地圖,寬高占手機(jī)窗口的100%
  • 地圖之上有五個(gè)按鈕圖標(biāo)和多個(gè)黃色ofo標(biāo)記:定位按鈕,立即用車按鈕,舉報(bào)按鈕,黃色頭像按鈕和位于地圖中心的定位標(biāo)記。


要在頁面顯示地圖,我們需要在index.wxml引入地圖組件:
  1. <!--index.wxml-->
  2. <view class="container">
  3.   <map id="ofoMap"
  4.     latitude="{{latitude}}"  // 緯度
  5.     longitude="{{longitude}}"  // 經(jīng)度
  6.     scale="{{scale}}"  // 縮放級(jí)別
  7.     show-location/>    // 顯示帶有方向的小圓點(diǎn)
  8. </view>
復(fù)制代碼

{{...}} 里面是模板數(shù)據(jù),待會(huì)會(huì)在index.js里的data對(duì)象里面定義。

初始化模板數(shù)據(jù),在index.js的data對(duì)象里添加如下代碼:
  1. //index.js
  2. Page({
  3.   data: {
  4.     scale: 18, // 縮放級(jí)別,默認(rèn)18,數(shù)值在0~18之間
  5.     latitude: 0, // 給個(gè)默認(rèn)值
  6.     longitude: 0 // 給個(gè)默認(rèn)值
  7.   },
  8.   onLoad: function(options){
  9.     // 1.頁面初始化 options為頁面跳轉(zhuǎn)所帶來的參數(shù)
  10.   },
  11.   onReady: function(){
  12.     // 頁面渲染完成
  13.   },
  14.   onShow: function(){
  15.     // 頁面顯示
  16.   },
  17.   onHide: function(){
  18.     // 頁面隱藏
  19.   },
  20.   onUnload: function(){
  21.     // 頁面關(guān)閉
復(fù)制代碼

這樣我們的地圖就默認(rèn)中心位置為經(jīng)度 0,緯度0。當(dāng)然可能在開發(fā)者工具里顯示不出來(有bug)。莫慌!因?yàn)檫@不是我們想要的,我們想要的是我們自己的位置,所以得先獲取我們當(dāng)前所在位置的經(jīng)緯度,在index.js里的onLoad方法里添加如下代碼:
  1. onLoad: function(options){
  2.   // 1.頁面初始化 options為頁面跳轉(zhuǎn)所帶來的參數(shù)
  3.   
  4.   // 2.調(diào)用wx.getLocation系統(tǒng)API,獲取并設(shè)置當(dāng)前位置經(jīng)緯度
  5.     wx.getLocation({
  6.       type: "gcj02", // 坐標(biāo)系類型
  7.       // 獲取經(jīng)緯度成功回調(diào)
  8.       success: (res) => { // es6 箭頭函數(shù),可以解綁當(dāng)前作用域的this指向,使得下面的this可以綁定到Page對(duì)象
  9.         this.setData({  // 為data對(duì)象里定義的經(jīng)緯度默認(rèn)值設(shè)置成獲取到的真實(shí)經(jīng)緯度,這樣就可以在地圖上顯示我們的真實(shí)位置
  10.           longitude: res.longitude,
  11.           latitude: res.latitude
  12.         })
  13.       }
  14.     });
復(fù)制代碼

tips:res是一參數(shù)對(duì)象,它是由調(diào)用的對(duì)應(yīng)API傳過來的,如果你想知道res的具體值,可以在成功回調(diào)函數(shù)里打?。篶onsole.log(res),然后在控制臺(tái)輸出,看看它包含什么內(nèi)容。在調(diào)用一個(gè)陌生API的時(shí)候可以用這種方法查看返回的對(duì)象數(shù)據(jù),對(duì)處理邏輯很有幫助。
我們?cè)诘貓D上顯示了我們的真實(shí)位置,但沒有移動(dòng)到頁面的中心位置,微信提供的wx.moveToLocation()函數(shù)可以把當(dāng)前位置移動(dòng)到地圖中心。修改index.js:
  1. //index.js
  2. Page({
  3.   data: {
  4.     scale: 18,
  5.     latitude: 0,
  6.     longitude: 0
  7.   },
  8. // 頁面加載
  9.   onLoad: function(options){
  10.   // 1.頁面初始化 options為頁面跳轉(zhuǎn)所帶來的參數(shù)
  11.   
  12.   // 2.調(diào)用wx.getLocation系統(tǒng)API,獲取并設(shè)置當(dāng)前位置經(jīng)緯度
  13.     wx.getLocation({
  14.       type: "gcj02", // 坐標(biāo)系類型
  15.       // 獲取經(jīng)緯度成功回調(diào)
  16.       success: (res) => { // es6 箭頭函數(shù),可以解綁當(dāng)前作用域的this指向,使得下面的this可以綁定到Page對(duì)象
  17.         this.setData({  // 為data對(duì)象里定義的經(jīng)緯度默認(rèn)值設(shè)置成獲取到的真實(shí)經(jīng)緯度,這樣就可以在地圖上顯示我們的真實(shí)位置
  18.           longitude: res.longitude,
  19.           latitude: res.latitude
  20.         })
  21.       }
  22.     });
  23. }
  24. // 頁面顯示
  25.   onShow: function(){
  26.     // 1.創(chuàng)建地圖上下文,移動(dòng)當(dāng)前位置到地圖中心
  27.     this.mapCtx = wx.createMapContext("ofoMap"); // 地圖組件的id
  28.     this.movetoPosition()
  29.   },
  30. // 定位函數(shù),移動(dòng)位置到地圖中心
  31.   movetoPosition: function(){
  32.     this.mapCtx.moveToLocation();
  33.   }
  34. })
復(fù)制代碼

我們?cè)趏nShow函數(shù)里為地圖組件(id為ofoMap)創(chuàng)建了一個(gè)地圖上下文,調(diào)用了自定義函數(shù)movetoPosition(),而在自定義函數(shù)里又調(diào)用了moveToLocation這個(gè)API,這樣,頁面一顯示就在地圖中心顯示當(dāng)前位置。

我們地圖上定位了我們的真實(shí)位置,但地圖組件還是默認(rèn)樣式(點(diǎn)擊調(diào)試,右側(cè)面板點(diǎn)擊wxml可以查看地圖組件的默認(rèn)格式),所以我們?yōu)榈貓D組件添加樣式,在index.wxss里編寫樣式:
  1. /**index.wxss**/
  2. .container{
  3.   position: relative;
  4.   width: 100%; // 寬度占滿設(shè)備
  5.   height: 100vh; // 高度占滿設(shè)備
  6. }
  7. #ofoMap{
  8.   position: absolute;
  9.   left: 0;
  10.   top: 0;
  11.   right: 0;
  12.   bottom: 0;
  13.   width: 100%;
  14.   height: 100%;
復(fù)制代碼

保存刷新,整個(gè)屏幕就都顯示地圖了>_<

我們?cè)賮硖砑拥貓D上的按鈕
其實(shí)這里的按鈕不是真正的按鈕,它們屬于地圖上的控件屬性,并且不隨著地圖移動(dòng)。這里有一個(gè)坑:
地圖組件屬于微信原生組件,層級(jí)最高,任何元素都不能在地圖之上顯示,即無論設(shè)置多大z-index都無法顯示。所以,要想在地圖上添加按鈕來滿足需求,就要用到地圖控件屬性。

要添加地圖控件,先在地圖組件里聲明controls="...":
  1. <!--index.wxml-->
  2. <view class="container">
  3.   <map id="ofoMap"
  4.     latitude="{{latitude}}"  // 緯度
  5.     longitude="{{longitude}}"  // 經(jīng)度
  6.     scale="{{scale}}"  // 縮放級(jí)別
  7.     controls="{{controls}}" // 地圖控件數(shù)組,多個(gè)控件存放在數(shù)組里
  8.     show-location/>    // 顯示帶有方向的小圓點(diǎn)
  9. </view>
復(fù)制代碼

然后在index.js設(shè)置controls(看代碼注釋了解具體用法)
  1. //index.js
  2. Page({
  3.   data: {
  4.     scale: 18,
  5.     latitude: 0,
  6.     longitude: 0
  7.   },
  8. // 頁面加載
  9.   onLoad: function(options){
  10.   // 1.頁面初始化 options為頁面跳轉(zhuǎn)所帶來的參數(shù)
  11.   
  12.   // 2.調(diào)用wx.getLocation系統(tǒng)API,獲取并設(shè)置當(dāng)前位置經(jīng)緯度
  13.     ...已省略
  14.    
  15.   // 3.設(shè)置地圖控件的位置及大小,通過設(shè)備寬高定位
  16.     wx.getSystemInfo({ // 系統(tǒng)API,獲取系統(tǒng)信息,比如設(shè)備寬高
  17.       success: (res) => {
  18.         this.setData({
  19.           // 定義控件數(shù)組,可以在data對(duì)象初始化為[],也可以不初始化,取決于是否需要更好的閱讀
  20.           controls: [{
  21.             id: 1, // 給控件定義唯一id
  22.             iconPath: '/images/location.png', // 控件圖標(biāo)
  23.             position: { // 控件位置
  24.               left: 20, // 單位px
  25.               top: res.windowHeight - 80, // 根據(jù)設(shè)備高度設(shè)置top值,可以做到在不同設(shè)備上效果一致
  26.               width: 50, // 控件寬度/px
  27.               height: 50 // 控件高度/px
  28.             },
  29.             clickable: true // 是否可點(diǎn)擊,默認(rèn)為true,可點(diǎn)擊
  30.           },
  31.           {
  32.             id: 2,
  33.             iconPath: '/images/use.png',
  34.             position: {
  35.               left: res.windowWidth/2 - 45,
  36.               top: res.windowHeight - 100,
  37.               width: 90,
  38.               height: 90
  39.             },
  40.             clickable: true
  41.           },
  42.           {
  43.             id: 3,
  44.             iconPath: '/images/warn.png',
  45.             position: {
  46.               left: res.windowWidth - 70,
  47.               top: res.windowHeight - 80,
  48.               width: 50,
  49.               height: 50
  50.             },
  51.             clickable: true
  52.           },
  53.           {
  54.             id: 4,
  55.             iconPath: '/images/marker.png',
  56.             position: {
  57.               left: res.windowWidth/2 - 11,
  58.               top: res.windowHeight/2 - 45,
  59.               width: 22,
  60.               height: 45
  61.             },
  62.             clickable: false
  63.           },
  64.           {
  65.             id: 5,
  66.             iconPath: '/images/avatar.png',
  67.             position: {
  68.               left: res.windowWidth - 68,
  69.               top: res.windowHeight - 155,
  70.               width: 45,
  71.               height: 45
  72.             },
  73.             clickable: true
  74.           }]
  75.         })
  76.       }
  77.     });
  78. }
  79. // 頁面顯示
  80.   onShow: function(){
  81.     ...已省略
  82.   },
  83. // 定位函數(shù),移動(dòng)位置到地圖中心
  84.   movetoPosition: function(){
  85.     this.mapCtx.moveToLocation();
  86.   }
  87. })
復(fù)制代碼

tips: 我們?cè)诮o控件設(shè)置top,left值時(shí),用到了設(shè)備寬高。這樣的話我們的控件位置就會(huì)在所有不同比例的設(shè)備上顯示相同的效果了

我們?cè)贋榈貓D控件綁定事件

現(xiàn)在地圖上總共有四個(gè)圖標(biāo)可點(diǎn)擊(地圖中心的標(biāo)記控件不需要點(diǎn)擊,是用來指示中心位置的),所有我們需要為每個(gè)控件綁定不同的事件以實(shí)現(xiàn)不同的功能:
  • 點(diǎn)擊定位控件,定位當(dāng)前位置到地圖中心,因?yàn)橛脩粼谕蟿?dòng)地圖,有時(shí)需要回到當(dāng)前所在位置。
  • 點(diǎn)擊立即用車控件,調(diào)用微信內(nèi)置掃碼功能。然后獲取開鎖密碼。
  • 點(diǎn)擊舉報(bào)按鈕,前往維修報(bào)障頁面。
  • 點(diǎn)擊用戶頭像按鈕,前往登錄頁面進(jìn)行登錄,查看余額,充值等操作

為控件綁定事件,同樣需要在地圖控件進(jìn)行聲明:
  1. <!--index.wxml-->
  2. <view class="container">
  3.   <map id="ofoMap"
  4.     latitude="{{latitude}}"  // 緯度
  5.     longitude="{{longitude}}"  // 經(jīng)度
  6.     scale="{{scale}}"  // 縮放級(jí)別
  7.     controls="{{controls}}" // 地圖控件數(shù)組,多個(gè)控件存放在數(shù)組里
  8.     bindcontroltap="bindcontroltap" // 控件點(diǎn)擊事件
  9.     show-location/>    // 顯示帶有方向的小圓點(diǎn)
  10. </view>
復(fù)制代碼


注意: bindcontroltap事件會(huì)響應(yīng)所有控件的點(diǎn)擊,所以,我們需要根據(jù)控件id來區(qū)分控件,然后響應(yīng)不同的事件。這就是為什么要給控件設(shè)置id。

在index.js添加bindcontroltap事件:
  1. //index.js
  2. Page({
  3.   data: {
  4.     scale: 18,
  5.     latitude: 0,
  6.     longitude: 0
  7.   },
  8. // 頁面加載
  9.   onLoad: function(options){
  10.   // 1.獲取定時(shí)器,用于判斷是否已經(jīng)在計(jì)費(fèi)
  11.     this.timer = options.timer;
  12.    
  13.   // 2.調(diào)用wx.getLocation系統(tǒng)API,獲取并設(shè)置當(dāng)前位置經(jīng)緯度
  14.     ...已省略
  15.    
  16.   // 3.設(shè)置地圖控件的位置及大小,通過設(shè)備寬高定位
  17.     ...已省略
  18. }
  19. // 地圖控件點(diǎn)擊事件
  20.   bindcontroltap: function(e){
  21.     // 判斷點(diǎn)擊的是哪個(gè)控件 e.controlId的值是當(dāng)前點(diǎn)擊控件的id。
  22.     switch(e.controlId){
  23.       // 點(diǎn)擊定位控件
  24.       case 1: this.movetoPosition();
  25.         break;
  26.       // 點(diǎn)擊立即用車,判斷當(dāng)前是否正在計(jì)費(fèi),此處只需要知道是調(diào)用掃碼,后面會(huì)講到這里的判斷條件
  27.       case 2: if(this.timer === "" || this.timer === undefined){
  28.           // 沒有在計(jì)費(fèi)就掃碼
  29.           wx.scanCode({
  30.             success: (res) => {
  31.               // 正在獲取密碼通知
  32.               wx.showLoading({
  33.                 title: '正在獲取密碼',
  34.                 mask: true // 顯示蒙層
  35.               })
  36.               // 請(qǐng)求服務(wù)器獲取密碼和車號(hào)
  37.               wx.request({
  38.                 url: 'https://www.easy-mock.com/mock/59098d007a878d73716e966f/ofodata/password',
  39.                 data: {},
  40.                 method: 'GET',
  41.                 success: function(res){
  42.                   // 請(qǐng)求密碼成功隱藏等待框
  43.                   wx.hideLoading();
  44.                   // 攜帶密碼和車號(hào)跳轉(zhuǎn)到密碼頁
  45.                   wx.redirectTo({
  46.                     url: '../scanresult/index?password=' + res.data.data.password + '&number=' + res.data.data.number,
  47.                     success: function(res){
  48.                       wx.showToast({
  49.                         title: '獲取密碼成功',
  50.                         duration: 1000
  51.                       })
  52.                     }
  53.                   })           
  54.                 }
  55.               })
  56.             }
  57.           })
  58.         // 當(dāng)前已經(jīng)在計(jì)費(fèi)就回退到計(jì)費(fèi)頁
  59.         }else{
  60.           wx.navigateBack({
  61.             delta: 1
  62.           })
  63.         }  
  64.         break;
  65.       // 點(diǎn)擊保障控件,跳轉(zhuǎn)到報(bào)障頁
  66.       case 3: wx.navigateTo({
  67.           url: '../warn/index'
  68.         });
  69.         break;
  70.       // 點(diǎn)擊頭像控件,跳轉(zhuǎn)到個(gè)人中心
  71.       case 5: wx.navigateTo({
  72.           url: '../my/index'
  73.         });
  74.         break;
  75.       default: break;
  76.     }
  77.   },
  78. // 頁面顯示
  79.   onShow: function(){
  80.     ...已省略
  81.   },
  82. // 定位函數(shù),移動(dòng)位置到地圖中心
  83.   movetoPosition: function(){
  84.     this.mapCtx.moveToLocation();
  85.   }
  86. })
復(fù)制代碼

這里用到的API:
掃碼API: wx.scanCode({})
顯示加載框: wx.showLoading()
隱藏加載框: wx.hideLoading()
顯示提示框: wx.showToast()
隱藏提示框: wx.hideToast()
向服務(wù)器發(fā)送請(qǐng)求:wx.request({})
關(guān)閉當(dāng)前頁面,跳轉(zhuǎn)到指定頁面: wx.redirectTo({})
保留當(dāng)前頁面,跳轉(zhuǎn)到指定頁面: wx.navigateTo({})
回退到指定頁面: wx.naivgateBack({})

查看詳細(xì)用法,查看官方API文檔

tips:  跳轉(zhuǎn)頁面?zhèn)鲄⑹纠?
  1. let num = 1;
  2. wx.navigateTo({
  3.     url: '../other/index?num=' + num
  4. });
  5. // other頁面onLoad接受參數(shù)
  6. onLoad: function(options){
  7.     console.log(options.num); // 1
  8. }
  9. // 多個(gè)參數(shù)用&分隔,如 'index?num=' + num + '&text=' + 'text'
  10.  
復(fù)制代碼

我們現(xiàn)在在地圖上添加單車標(biāo)記makers和位置連線,還是在地圖組件里先聲明:
  1. <!--index.wxml-->
  2. <view class="container">
  3.   <map id="ofoMap"
  4.     latitude="{{latitude}}"  // 緯度
  5.     longitude="{{longitude}}"  // 經(jīng)度
  6.     scale="{{scale}}"  // 縮放級(jí)別
  7.     controls="{{controls}}" // 地圖控件數(shù)組,多個(gè)控件存放在數(shù)組里
  8.     bindcontroltap="bindcontroltap" // 控件點(diǎn)擊事件
  9.     polyline="{{polyline}}"  // 位置連線
  10.     markers="{{markers}}" // 標(biāo)記數(shù)組
  11.     bindmarkertap="bindmarkertap" // 標(biāo)記點(diǎn)擊事件
  12.     show-location/>    // 顯示帶有方向的小圓點(diǎn)
  13. </view>
復(fù)制代碼

然后在index.js里定義:
  1. //index.js
  2. Page({
  3.   data: {
  4.     scale: 18,
  5.     latitude: 0,
  6.     longitude: 0
  7.   },
  8. // 頁面加載
  9.   onLoad: function(options){
  10.   // 1.獲取定時(shí)器,用于判斷是否已經(jīng)在計(jì)費(fèi)
  11.     this.timer = options.timer;
  12.    
  13.   // 2.調(diào)用wx.getLocation系統(tǒng)API,獲取并設(shè)置當(dāng)前位置經(jīng)緯度
  14.     ...已省略
  15.    
  16.   // 3.設(shè)置地圖控件的位置及大小,通過設(shè)備寬高定位
  17.     ...已省略
  18.    
  19.   // 4.請(qǐng)求服務(wù)器,顯示附近的單車,用marker標(biāo)記
  20.     wx.request({
  21.       url: 'https://www.easy-mock.com/mock/59098d007a878d73716e966f/ofodata/biyclePosition',
  22.       data: {},
  23.       method: 'GET',
  24.       // header: {}, // 設(shè)置請(qǐng)求的 header
  25.       success: (res) => {
  26.           this.setData({
  27.             markers: res.data.data
  28.           })
  29.       }
  30.     })
  31. }
  32. // 地圖控件點(diǎn)擊事件
  33.   bindcontroltap: function(e){
  34.     ...已省略
  35.   },
  36. // 地圖標(biāo)記點(diǎn)擊事件,連接用戶位置和點(diǎn)擊的單車位置
  37.   bindmarkertap: function(e){
  38.     let _markers = this.data.markers; // 拿到標(biāo)記數(shù)組
  39.     let markerId = e.markerId; // 獲取點(diǎn)擊的標(biāo)記id
  40.     let currMaker = _markers[markerId]; // 通過id,獲取當(dāng)前點(diǎn)擊的標(biāo)記
  41.     this.setData({
  42.       polyline: [{
  43.         points: [{ // 連線起點(diǎn)
  44.           longitude: this.data.longitude,
  45.           latitude: this.data.latitude
  46.         }, { // 連線終點(diǎn)(當(dāng)前點(diǎn)擊的標(biāo)記)
  47.           longitude: currMaker.longitude,
  48.           latitude: currMaker.latitude
  49.         }],
  50.         color:"#FF0000DD", // 連線顏色
  51.         width: 1, // 連線寬度
  52.         dottedLine: true // 虛線
  53.       }],
  54.       scale: 18
  55.     })
  56.   },
  57. // 頁面顯示
  58.   onShow: function(){
  59.     ...已省略
  60.   },
  61. // 定位函數(shù),移動(dòng)位置到地圖中心
  62.   movetoPosition: function(){
  63.     this.mapCtx.moveToLocation();
  64.   }
  65. })
復(fù)制代碼

我在easy-mock上偽造了一些單車的經(jīng)緯度,是基于我自己的位置。你可以在你周圍設(shè)置經(jīng)緯度,使用easy-mock偽造??梢钥匆幌挛业臄?shù)據(jù)格式,單車經(jīng)緯度接口

接下來我們?yōu)橛脩敉蟿?dòng)地圖綁定事件
我們已經(jīng)為地圖控件和標(biāo)記響應(yīng)了不同的事件,現(xiàn)在如果用戶拖動(dòng)地圖,我們需要在拖動(dòng)附近顯示單車,先在地圖組件聲明地圖拖動(dòng)事件:
  1. <!--index.wxml-->
  2. <view class="container">
  3.   <map id="ofoMap"
  4.     latitude="{{latitude}}"  // 緯度
  5.     longitude="{{longitude}}"  // 經(jīng)度
  6.     scale="{{scale}}"  // 縮放級(jí)別
  7.     controls="{{controls}}" // 地圖控件數(shù)組,多個(gè)控件存放在數(shù)組里
  8.     bindcontroltap="bindcontroltap" // 控件點(diǎn)擊事件
  9.     polyline="{{polyline}}"  // 位置連線
  10.     markers="{{markers}}" // 標(biāo)記數(shù)組
  11.     bindmarkertap="bindmarkertap" // 標(biāo)記點(diǎn)擊事件
  12.     bindregionchange="bindregionchange" // 拖動(dòng)地圖事件
  13.     show-location/>    // 顯示帶有方向的小圓點(diǎn)
  14. </view>
  15.  
復(fù)制代碼

然后在index.js里實(shí)現(xiàn)這個(gè)事件方法:
  1. //index.js
  2. Page({
  3.   data: {
  4.     scale: 18,
  5.     latitude: 0,
  6.     longitude: 0
  7.   },
  8. // 頁面加載
  9.   onLoad: function(options){
  10.   // 1.獲取定時(shí)器,用于判斷是否已經(jīng)在計(jì)費(fèi)
  11.     this.timer = options.timer;
  12.    
  13.   // 2.調(diào)用wx.getLocation系統(tǒng)API,獲取并設(shè)置當(dāng)前位置經(jīng)緯度
  14.     ...已省略
  15.    
  16.   // 3.設(shè)置地圖控件的位置及大小,通過設(shè)備寬高定位
  17.     ...已省略
  18.    
  19.   // 4.請(qǐng)求服務(wù)器,顯示附近的單車,用marker標(biāo)記
  20.     ...已省略
  21. }
  22. // 地圖控件點(diǎn)擊事件
  23.   bindcontroltap: function(e){
  24.     ...已省略
  25.   },
  26. // 拖動(dòng)地圖事件
  27.   bindregionchange: function(e){
  28.     // 拖動(dòng)地圖,獲取附件單車位置
  29.     if(e.type == "begin"){
  30.       wx.request({
  31.         url: 'https://www.easy-mock.com/mock/59098d007a878d73716e966f/ofodata/biyclePosition',
  32.         data: {},
  33.         method: 'GET',
  34.         success: (res) => {
  35.           this.setData({
  36.             _markers: res.data.data
  37.           })
  38.         }
  39.       })
  40.     // 停止拖動(dòng),顯示單車位置
  41.     }else if(e.type == "end"){
  42.         this.setData({
  43.           markers: this.data._markers
  44.         })
  45.     }
  46.   },
  47. // 地圖標(biāo)記點(diǎn)擊事件,連接用戶位置和點(diǎn)擊的單車位置
  48.   bindmarkertap: function(e){
  49.     ...已省略
  50.   },
  51. // 頁面顯示
  52.   onShow: function(){
  53.     ...已省略
  54.   },
  55. // 定位函數(shù),移動(dòng)位置到地圖中心
  56.   movetoPosition: function(){
  57.     this.mapCtx.moveToLocation();
  58.   }
  59. })
復(fù)制代碼


至此,首頁地圖已經(jīng)完成了,下一節(jié)我們要編寫響應(yīng)的跳轉(zhuǎn)頁面

其他章節(jié)
微信小程序開發(fā)之OFO共享單車——掃碼
微信小程序開發(fā)之OFO共享單車——單車報(bào)障頁
微信小程序開發(fā)之OFO共享單車——個(gè)人中心頁
微信小程序開發(fā)之OFO共享單車——錢包與充值

重磅推薦:小程序開店目錄

第一部分:小商店是什么

第二部分:如何開通一個(gè)小商店

第三部分:如何登錄小商店

第四部分:開店任務(wù)常見問題

第五部分:小商店可以賣什么

第六部分:HiShop小程序特色功能

第七部分:小程序直播

第八部分:小程序收貨/物流

第九部分:小程序怎么結(jié)算

第十部分:小程序客服

第十一部分:電商創(chuàng)業(yè)

第十二部分:小程序游戲開發(fā)