微信小程序中正確使用地圖的方法實(shí)例
前言
今天是我的小兄弟(微信小程序方面)在工作中遇到的一個(gè)場(chǎng)景——選擇某個(gè)位置周?chē)膶W(xué)校,感覺(jué)很有用,就讓他給大家分享一下。
這次想分享一下關(guān)于微信小程序中選擇全國(guó)中的一個(gè)學(xué)校和地址的方法,經(jīng)過(guò)調(diào)研發(fā)現(xiàn)大多網(wǎng)站提供全國(guó)學(xué)校名稱的是比較老的一些學(xué)校,像比較新或者地方比較偏僻的學(xué)校一般都找不到。想想這樣是肯定不行的,那就繼續(xù)尋找能更全面的方式,最終想到了地圖中提供的服務(wù)提供的學(xué)校最全面,這里就采用騰訊地圖的開(kāi)放接口作為示例演示。
1. 準(zhǔn)備
通過(guò)閱讀騰訊地圖開(kāi)放平臺(tái)可以得知微信小程序可以下載SDK提供直接調(diào)用接口來(lái)使用騰訊地圖,當(dāng)然也可以自己對(duì)URL進(jìn)行封裝請(qǐng)求并返回自己的數(shù)據(jù),本示例均使用了,因?yàn)镾DK中封裝時(shí)會(huì)調(diào)用某些接口,而在示例中會(huì)多時(shí)間內(nèi)調(diào)用同一接口,那么就會(huì)造成頻繁調(diào)用接口的錯(cuò)誤。
過(guò)程中我也會(huì)用有贊團(tuán)隊(duì)的vant來(lái)展示學(xué)校信息,所以也需要提前安裝好依賴備用,具體安裝步驟見(jiàn)官網(wǎng)
2. 實(shí)戰(zhàn)
2.1 配置小程序權(quán)限
首先就是在進(jìn)入小程序時(shí)讓用戶給我們的小程序開(kāi)啟定位的權(quán)限,需要我們?cè)赼pp.json文件中添加以下代碼:
"permission": { "scope.userLocation": { "desc": "你的位置信息將用于小程序位置接口的效果展示" } }
加上這一字段,當(dāng)小程序用到定位系統(tǒng)時(shí),發(fā)現(xiàn)小程序的權(quán)限沒(méi)給到就會(huì)讓用戶將權(quán)限給到小程序,效果如下:
2.2 封裝工具函數(shù)
2.2.1 全局函數(shù)與變量
app.js
// 全局變量 globalData: { userInfo: null }, // 全局引入方法,簡(jiǎn)便引入第三方包 require: ($url)=> require($url)
2.2.2 工具函數(shù)
util.js
// 引入SDK核心類 const QQMapWX = require('./qqmap-wx-jssdk.min.js'); // 實(shí)例化API核心類 let key = ''; let qqmapsdk; key &&(qqmapsdk = new QQMapWX({ key // 必填 })); module.exports = { qqmapsdk, key }
這里我們引入SDK,并且將實(shí)例化對(duì)象直接傳出去,但是這里需要給上騰訊的地圖開(kāi)放接口秘鑰,這里我的key就不提供了,將key傳出去是因?yàn)槲覀兒竺嫘枰褂?,為了不暴露自己的key,一般在開(kāi)發(fā)時(shí),key一般存儲(chǔ)在后端的config中的,這里為了方便演示就在前端做處理了。
2.3 跳轉(zhuǎn)選址頁(yè)面前的處理
手機(jī)要定位不僅需要微信權(quán)限開(kāi)啟,還有我們的手機(jī)也有一個(gè)定位系統(tǒng)權(quán)限也要開(kāi)啟,所以在正式開(kāi)始定位前,為了用戶的更好體驗(yàn)我們這一塊功能我們通常還需要一系列的操作,這里我簡(jiǎn)單的用button來(lái)用作跳轉(zhuǎn)。
wxml
<view> <van-btn bind:tap="gotoMap" type="info">前往使用地圖</van-btn> </view>
首先我們需要為按鈕添加一個(gè)點(diǎn)擊事件,這里我們可以處理很多事情;接下來(lái)讓我們來(lái)看看js代碼吧!
// 引入所需的工具函數(shù) const app = getApp(); const {qqmapsdk} = app.require('utils/util'); Page({ /** * 地圖開(kāi)始位置 */ // 點(diǎn)擊按鈕跳轉(zhuǎn)到地圖頁(yè)面 gotoMap(){ wx.showLoading({ title: "正在跳轉(zhuǎn)至地圖頁(yè)" }) // 跳轉(zhuǎn)前要做幾件事情提高用戶體驗(yàn)性 // 1. 要驗(yàn)證用戶是否開(kāi)啟了定位,沒(méi)有的話就引導(dǎo) // 2. 還需驗(yàn)證程序的定位權(quán)限,沒(méi)有的話就引導(dǎo) // 3. 做好上面的兩點(diǎn)才可以開(kāi)始跳轉(zhuǎn)了 wx.getLocation({ success(res){ wx.navigateTo({ url: "/pages/map/index" }) }, fail(e){ if (e && (e.errCode == 2 || e.errCode == 404)) { wx.showModal({ title: "提示", content: '位置信息獲取失敗,請(qǐng)檢查手機(jī)“位置信息”是否未開(kāi)啟', showCancel: false }) } else if (e && ((e.errMsg.indexOf('getLocation:fail auth deny') != -1) || (e.errMsg.indexOf('system permission denied') != -1))) { showModal({ title: "提示", content: '位置信息獲取失敗,請(qǐng)檢查微信是否有定位權(quán)限', confirmText: "重新獲取", success(res){ if(res.confirm === true){ detectSettings() } else if(res.cancel == true){ return; } } }) } else if(e.errMsg.indexOf("頻繁") !== -1){ wx.showModal({ title: "提示", content: "位置信息接口調(diào)用太頻繁了,請(qǐng)等10-30秒后再操作。", showCancel: false }) } }, complete(){ wx.hideLoading() } }) // 引導(dǎo)開(kāi)啟微信定位權(quán)限 function detectSettings(){ wx.getSetting({ success(res){ if(res && (res.authSetting["scope.userLocation"] !== undefined && res.authSetting["scope.userLocation"] !==true)){ wx.showModal({ title: "提示", content:"小程序沒(méi)有定位權(quán)限,請(qǐng)前往設(shè)置微信小程序的定位權(quán)限。", confirmText: "前往設(shè)置", success(res){ if(res.cancel == true){ return } else if (res.confirm === true){ wx.openSetting({ success(result){ if(result && (result.authSetting["scope.userLocation"] !== undefined && result.authSetting["scope.userLocation"] ===true)){ wx.navigateTo({ url: "/pages/map/index" }) } else { wx.navigateTo({ url: "/pages/index/index" }) } }, }) } }, fail(){ wx.navigateTo({ url: "/pages/index/index" }) } }) } else { wx.navigateTo({ url: "/pages/map/index" }) } }, complete(){ wx.hideLoading() } }) } } })
看完代碼就看看效果吧,我們這里著重說(shuō)明沒(méi)有符合跳轉(zhuǎn)的條件,效果如下GIF所示:
上面的GIF沒(méi)有對(duì)手機(jī)定位系統(tǒng)未開(kāi)做處理,這個(gè)演示在這個(gè)方面的處理比較簡(jiǎn)單,僅僅是提示一下就沒(méi)了,日常開(kāi)發(fā)中一般會(huì)有其他的更好的處理方式,未開(kāi)的效果如下:
2.4 跳轉(zhuǎn)后的處理
2.4.1 頁(yè)面初始化
經(jīng)過(guò)上一步的處理我們已經(jīng)已經(jīng)確定了,手機(jī)的兩個(gè)權(quán)限都給到了,那么我們開(kāi)始處理地圖選址頁(yè)面的處理,開(kāi)始之前先看看成品是什么樣的,如下:
wxml
<!--pages/map/index.wxml--> <view class="fixed top"> <van-search bind:search="searchSchool" placeholder="請(qǐng)輸入學(xué)校名稱" model:value="{{schoolName}}" /> <view class="school-nav"> <text class="left">附近的學(xué)校</text> <view class="right" bind:tap="changeCity"> <van-icon name="location-o" /> <text>{{city || "北京市"}}</text> </view> </view> </view> <view class="addr-cell" bindtap="subData"> <block wx:for="{{options}}" wx:key="index"> <van-cell data-chooseOpt="{{item}}" title-width="70vw" title="{{item.title}}" value="" label="{{item.address}}" /> </block> <view id="txt" class="btm"> <text wx:if="{{options.length}}">{{count>0 ? "下拉刷新獲取更多信息" : "已經(jīng)到底了"}}</text> <text class="no-data" wx:else>沒(méi)有獲取到相關(guān)的數(shù)據(jù)。。。</text> </view> </view>
整體框架就如上面的wxml所示,如果將數(shù)據(jù)全部提供就會(huì)像上圖所示。那么接著說(shuō)明一下他的邏輯實(shí)現(xiàn)吧!
// 引入所需的工具函數(shù) const app = getApp(); const {qqmapsdk,key} = app.require('utils/util'); // 初始化生命周期函數(shù) onLoad: function (options) { _this = this; _this.init() },
下面的函數(shù)不僅僅在加載時(shí)用到,在后面也會(huì)用到,我用傳入的參數(shù)來(lái)區(qū)別。如果是在加載時(shí)調(diào)用,他僅僅是為了獲取到用戶的當(dāng)前位置,獲取到的位置用于顯示;如果傳入一個(gè)地址就將用于地址逆解析的。
// 你地址解析和獲取當(dāng)前位置 init(location){ let query = { success(res){ console.log(res) if(res.status === 0) { // console.log(res.result.location) app.globalData.adInfo = res.result.ad_info; _this.setData({ city: res.result.ad_info.city, lat: res.result.location.lat, lng: res.result.location.lng, }) _this.qqSearch(); } else { wx.showModal({ title: '提示', content:res.message || "獲取地理位置信息失敗。", showCancel: false }) } }, fail(e){ console.log(e) } } location && (query.location = location); qqmapsdk.reverseGeocoder(query); }
2.4.2 搜索功能實(shí)現(xiàn)
// 如果輸入的是一個(gè)城市,就只會(huì)顯示城市而不會(huì)顯示學(xué)校 searchSchool(e){ // 沒(méi)輸入或者輸入空格 if(e && (!e.detail || e.detail.trim() === '')){ wx.showToast({ title: "請(qǐng)輸入有效的學(xué)校名稱", icon: 'none', duration: 2000 }) return } _this.setData({ options:[], count: -2 }) _this.qqSearch(e.detail); }, qqSearch(name){ // 輸入框輸入的學(xué)校名稱 wx.showLoading({ title: "正在獲取信息" }) const mks = []; let count, boundary= `nearby(${_this.data.lat},${_this.data.lng},1000)`; search(name) function search(name){ const opts = { keyword: '大學(xué)', //搜索關(guān)鍵詞 page_size: 15, page_index: _this.data.pageIndex, // 獲取更多 key: key, boundary }; if(name){ opts.boundary = `region(${_this.data.city})` opts.keyword = name } // 這里主要是避免高頻調(diào)用接口而導(dǎo)致的錯(cuò)誤,所以只能使用URL獲取相關(guān)信息 wx.request({ url: "https://apis.map.qq.com/ws/place/v1/search", method: "get", data:{ ...opts }, success: function (res) { //搜索成功后的回調(diào) console.log(res) if(res.statusCode !== 200 || (res.data && res.data.status !== 0)) return; // 初始化和其他狀態(tài) // 計(jì)算可以下滑幾次獲取更多 if(_this.data.count === -1 || _this.data.count === -2){ count = res.data.count && Math.floor(res.data.count/10); }else { count = --_this.data.count; } for (let i = 0; i < res.data.data.length; i++) { mks.push({ // 獲取返回結(jié)果,放到mks數(shù)組中 title: res.data.data[i].title, address: res.data.data[i].address, }) } }, fail: function (e) { console.log(e) wx.showToast({ title: JSON.stringify(e) || "獲取地圖信息失敗", icon: "none", duration: 3000 }) }, complete: function (){ setTimeout(()=>{ wx.hideLoading() mks.push(..._this.data.options); _this.setData({ //設(shè)置markers屬性,將搜索結(jié)果顯示在地圖中 options: mks, count }) },1000) } }); } },
2.4.3 下滑到底獲取更多
// 下滑到底生命周期函數(shù) onReachBottom: function () { _this.data.pageIndex = ++_this.data.pageIndex; _this.data.count && _this.qqSearch(); },
2.4.4 提交數(shù)據(jù)
對(duì)于提交數(shù)據(jù)這里就不多做處理了,選擇的話就提示一下,在實(shí)際開(kāi)發(fā)中一般都需要將數(shù)據(jù)存到數(shù)據(jù)庫(kù)中另作他用。
subData(e){ const data = e.target.dataset.chooseopt; // 處理點(diǎn)擊提示文字的情況 if(!data) return; wx.showModal({ title: "提示", content: `您所在學(xué)校是【${data.title}】嗎?`, success(res){ // 取消 if(res.cancel) { return; } else if (res.confirm){ // 確定 // 向后端請(qǐng)求添加或者修改,一般需要詳細(xì)的地址,這里簡(jiǎn)單處理 wx.showToast({ title: data.title, icon: "none" }) } }, fail(){ wx.showToast({ title: "失敗", icon: "error" }) } }) }
2.4.5 切換城市
changeCity(){ _this.setData({ options:[], count:-2, // 簡(jiǎn)易的雙向數(shù)據(jù)綁定,進(jìn)入就清空輸入框的內(nèi)容 schoolName: '' }) wx.chooseLocation({ latitude:_this.data.lat, longitude:_this.data.lng, success(res){ if(res.errMsg === "chooseLocation:ok"){ // 獲取到選擇的位置,會(huì)通過(guò)地址逆解析去解析經(jīng)緯度 _this.init(`${res.latitude},${res.longitude}`); } }, // 按取消按鈕 fail(e){ if(e.errMsg === "chooseLocation:fail cancel"){ _this.init(); } }, complete(){ } }) }
到此,微信小程序?qū)W校選擇就全部完成了,此次實(shí)戰(zhàn)一步一步慢慢實(shí)現(xiàn)下來(lái)邏輯并不復(fù)雜。
總結(jié)
到此這篇關(guān)于微信小程序中正確使用地圖的文章就介紹到這了,更多相關(guān)微信小程序使用地圖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 微信小程序 地圖定位簡(jiǎn)單實(shí)例
- 微信小程序 地圖(map)實(shí)例詳解
- 微信小程序中進(jìn)行地圖導(dǎo)航功能的實(shí)現(xiàn)方法
- 微信小程序 使用騰訊地圖SDK詳解及實(shí)現(xiàn)步驟
- 微信小程序 高德地圖SDK詳解及簡(jiǎn)單實(shí)例(源碼下載)
- 微信小程序 地圖map詳解及簡(jiǎn)單實(shí)例
- 微信小程序開(kāi)發(fā)之map地圖實(shí)現(xiàn)教程
- 微信小程序之獲取當(dāng)前位置經(jīng)緯度以及地圖顯示詳解
- 微信小程序教程之本地圖片上傳(leancloud)實(shí)例詳解
- 微信小程序地圖(map)組件點(diǎn)擊(tap)獲取經(jīng)緯度的方法
相關(guān)文章
詳解JavaScript如何實(shí)現(xiàn)一個(gè)簡(jiǎn)易的Promise對(duì)象
Promise對(duì)象的作用將異步操作以同步操作的流程表達(dá)出來(lái),避免層層嵌套的回調(diào)函數(shù),而且Promise提供了統(tǒng)一的接口,使得控制異步操作更加容易。本文介紹了如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的Promise對(duì)象,需要的可以參考一下2022-11-11經(jīng)常用到的javascript驗(yàn)證函數(shù)收集
經(jīng)常用到的javascript驗(yàn)證函數(shù)收集...2007-11-11javascript模版引擎-tmpl的bug修復(fù)與性能優(yōu)化分析
在平時(shí)編碼中,經(jīng)常要做拼接字符串的工作,如把json數(shù)據(jù)用HTML展示出來(lái),以往字符串拼接與邏輯混在在一起會(huì)讓代碼晦澀不堪,加大了多人協(xié)作與維護(hù)的成本。而采用前端模板機(jī)制就能很好的解決這個(gè)問(wèn)題2011-10-10Js之軟鍵盤(pán)實(shí)現(xiàn)(js源碼)
Js之軟鍵盤(pán)實(shí)現(xiàn)(js源碼)...2007-01-01js動(dòng)態(tài)設(shè)置select下拉菜單的默認(rèn)選中項(xiàng)實(shí)例
今天小編就為大家分享一篇js動(dòng)態(tài)設(shè)置select下拉菜單的默認(rèn)選中項(xiàng)實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08