1. 程式人生 > 其它 >你的班車在哪裡——我的首個微信小程式開發歷程和技術總結

你的班車在哪裡——我的首個微信小程式開發歷程和技術總結

毫無疑問,漫無目的的寫程式碼是效率極其低下的,不論對於學習又或者是工作,所以我一直堅信需求才是創作的源動力。這個小程式謀劃已久,可能從開始來712工作就有了這個想法,對於我這種對天津大街小巷還不夠熟悉的人來說,每次租房對照著線路圖不停的在地圖上搜索標註班車站點是很費力的工作,這個一鍵搜尋的需求也就產生了。

本文案例是一個面向需求程式設計產生的實現查詢班車線路功能的微信小程式
環境:微信開發者工具 預釋出版 RC Build (1.05.2107221)

面向需求程式設計

毫無疑問,漫無目的的寫程式碼是效率極其低下的,不論對於學習又或者是工作,所以我一直堅信需求才是創作的源動力。這個小程式謀劃已久,可能從開始來712工作就有了這個想法,對於我這種對天津大街小巷還不夠熟悉的人來說,每次租房對照著線路圖不停的在地圖上搜索標註班車站點是很費力的工作,這個一鍵搜尋的需求也就產生了。

先看最終成品吧

一共包含兩個功能,第一是查詢最近站點,根據你的定位搜尋離你最近的班車站點,預設顯示最近的三個。第二個功能是檢視所有線路,可以根據選擇的線路和站點顯示其資訊和地圖定位。

技術總結

佈局

這個沒有太多可以說的,前端的基本功吧,wxml與html僅標籤有所更換,wxss和css可能是完全相同。

定位獲取

這裡使用的是微信小程式位置api:wx.startLocationUpdate(Object object),會提示使用者獲取定位許可權,每30秒進行一次回撥,注意在使用完以後使用api:wx.stopLocationUpdate(Object object)關閉獲取定位,防止耗電增加。

//開啟小程式進入前臺時接收位置訊息
wx.startLocationUpdate()
//關閉監聽實時位置變化,前後臺都停止訊息接收
wx.stopLocationUpdate()

介面地圖

這裡使用的是小程式的map控制元件,來自於騰訊地圖,設定其中心經緯度和標記點的經緯度即可。

<map class="map" longitude="{{longitude}}" 
                 latitude="{{latitude}}" 
                 markers="{{[{latitude:latitude, longitude:longitude}]}}"
</map>

騰訊地圖開放平臺

這裡使用的是微信小程式JavaScriptSDK,主要使用了逆地址解析(座標位置描述)和距離計算兩個api。

//引入SDK,並建立其例項
var QQMapWX = require('../../utils/qqmap-wx-jssdk.min.js')
var qqmapsdk = new QQMapWX({
      key: '開發者金鑰'
  })
//逆地址解析(座標位置描述)
qqmapsdk.reverseGeocoder({
    //如果不設定座標,預設使用的就是當前位置
    //如果查詢成功的回撥函式
    success(res) {
        //獲取地標位置資訊
        var famousArea = res.result.address_reference.landmark_l1 || res.result.address_reference.landmark_l2
        var tempLocation = {
            name: famousArea.title,
            longitude: famousArea.location.lng,
            latitude: famousArea.location.lat
        }
        //設定Data屬性
        _this.setData({
            currentLocation: tempLocation,
            markers: [
                {
                    longitude: tempLocation.longitude,
                    latitude: tempLocation.latitude
                }
            ]
        })
    },
    //如果失敗成功的回撥函式
    fail(err) {
        _this.setData({
            locationState: "To location failure"
        })
    },
    //呼叫完成停止定位
    complete(res) {
        wx.stopLocationUpdate({
            success: (res) => {
                _this.setData({
                    locationState: "Complete"
                })
            },
        })
    }
})
//距離計算
//從資料來源bus構建目的地格式的陣列
var distancePar = []
for (const item of bus) {
    var tempLocation = {
        longitude: item.longitude,
        latitude: item.latitude
    }
    distancePar.push(tempLocation);
}
qqmapsdk.calculateDistance({
    //設定出發地座標
    from: {
        longitude: _this.data.currentLocation.longitude,
        latitude: _this.data.currentLocation.latitude
    },
    //設定目的地座標,傳入上面構建的陣列
    to: distancePar,
    //查詢成功的回撥函式
    success(res) {
        var distance = res.result.elements
        var minLocation = []
        //通過收到的資料反查本地資料來源,找到座標與實際站點的對應關係
        distance.forEach((item, index) => {
            var tempSortMinLocation = {}
            tempSortMinLocation.bus = bus[index]
            tempSortMinLocation.distance = item.distance
            minLocation.push(tempSortMinLocation)
        });
        //對結果按照距離屬性進行排序
        minLocation.sort((property => {
            return (a, b) => {
                var value1 = a[property];
                var value2 = b[property];
                return value1 - value2;
            }
        })('distance'))
        //將排序後的結果存入快取
        wx.setStorage({
            key: "minLocation",
            data: minLocation
        })
        _this.setData({
            isLoading: false
        })
        //跳轉到結果顯示頁面
        wx.navigateTo({
            url: '/pages/busResult/busResult',
        })
    },
    //查詢失敗的回撥函式
    fail(err) {
        _this.setData({
            locationState: "Route query failure"
        })
    }
})

選擇其他位置

使用的小程式位置api:wx.chooseLocation(Object object)

wx.chooseLocation({
    //標記初始位置為當前定位
    longitude: this.data.currentLocation.longitude,
    latitude: this.data.currentLocation.latitude,
    //選擇確定後
    success(res) {
        //設定新的地圖中心的標誌點
        _this.setData({
            currentLocation: {
                name: res.name,
                longitude: res.longitude,
                latitude: res.latitude,
            },
            markers: [
                {
                    longitude: res.longitude,
                    latitude: res.latitude
                }
            ],
            locationState: "Complete"
        })
    },
    //選擇取消後更改定位狀態
    fail(err) {
        _this.setData({
            locationState: "To location failure"
        })
    }
})

所有路線篩選功能

這裡主要功能不是我自己開發的,使用了Github上找到了一個元件。

開發者:Devin 地址:https://github.com/ZBK1nger/dropDownMenu-wechat

按照說明匯入後,簡單設定即可,下面介紹一下我構建其需求資料型別的過程。

//在onLoad時期,執行新增導航欄的任務
addNavItem() {
    var tempBusLines = []
    var tempChildModel = []
    //第一個迴圈,迴圈新增35條班車線路一級選單
    for (let index = 1; index <= 35; index++) {
        var tempChildModel = []
        tempChildModel.push({
            id: `${index}`,
            title: "全部"
        })
        //內層forEach迴圈,構建一級選單所需的二級選單
        this.data.bus.forEach(item => {
            if (item.line == index) {
                tempChildModel.push({
                    id: `${item.line}`,
                    title: `${item.title}`
                })
            }
        })
        //使用二級選單構建一級選單
        var temp = {
            id: index,
            title: `${index}號車`,
            childModel: tempChildModel
        }
        tempBusLines.push(temp)
        temp = {}
        tempChildModel = []
    }
    //設定資料
    this.setData({
        busLines: tempBusLines
    })
    tempBusLines = []
}
//點選二級選單後的事件處理器
selectedItem: function(e) {
    var chooseBus = []
    //如果選擇的是某條線路的全部
    if (e.detail.selectedTitle == "全部") {
        this.data.bus.forEach(item => {
            if (item.line == e.detail.selectedId) {
                chooseBus.push(item)
            }
        })
        this.setData({
            tempBus: chooseBus
        })
        chooseBus = []
    } else { //如果選擇的是某一站點
        this.data.bus.forEach(item => {
            if (item.title == e.detail.selectedTitle) {
                chooseBus.push(item)
            }
            this.setData({
                tempBus: chooseBus
            })
        })
        chooseBus = []
    }
}

結尾

這次開發耗時幾天,功能算是非常簡單和基礎,其中難免有不妥當之處,懇請指正。
所有原始碼已上傳我的Github,需要的可以去看看。
小程式二維碼放在這裡吧,歡迎大家訪問看看實際效果。

作者:chanstic
出處:你的班車在哪裡——我的首個微信小程式開發歷程和技術總結
本作品採用「CC BY-NC-SA 4.0」許可協議進行許可