本文實(shí)例講述了微信小程序常用簡(jiǎn)易小函數(shù)。分享給大家供大家參考,具體如下:
最近一直在寫(xiě)微信小程序,而且由于是第二次寫(xiě)了,所以針對(duì)很多通用的情況封裝了一些函數(shù),建議你們放在app.js中,方便全局去調(diào)用。
提示類(lèi)函數(shù)
微信有一種原生的API用于顯示提示類(lèi)結(jié)果的wx.showToast
,而且其中的圖片是可以自定義的,所以為了保證全部一致性,而且方便調(diào)用,所以我將其全部封裝在了app.js中:
// 成功showSuccess: function (message) { wx.showToast({ title: message, duration: 2000, image: "/images/Common/Success.png", }) },// 錯(cuò)誤showError: function (message) { wx.showToast({ title: message, duration: 2000, image: "/images/Common/Error.png", }) },// 警告showWarn: function (message) { wx.showToast({ title: message, duration: 2000, image: "/images/Common/Warn.png", }) }
注意上面的duration參數(shù),這個(gè)在下面的情況中是一個(gè)很重要的問(wèn)題。
假設(shè)一般的操作是對(duì)一個(gè)頁(yè)面的操作完成后接著顯示處理結(jié)果,最后進(jìn)行跳轉(zhuǎn)。所以這里就存在一個(gè)問(wèn)題,假設(shè)使用上面的彈出框進(jìn)行顯示,那么在彈出框顯示之前就會(huì)進(jìn)行跳轉(zhuǎn),這樣處理結(jié)果就顯示不全了,所以合理的做法是在彈出框結(jié)束后進(jìn)行跳轉(zhuǎn)。而如果將跳轉(zhuǎn)單獨(dú)封裝在各個(gè)頁(yè)面中,那么到時(shí)候進(jìn)行時(shí)間長(zhǎng)短的處理就很麻煩了,所以我將這個(gè)函數(shù)進(jìn)行了封裝:
// 第一個(gè)是路由,第二個(gè)則是判斷是否是tabbar的路由,跳這兩個(gè)路由是不一致的completeOperating:function(to,isTabbar){ var time=setTimeout(function(){ if(isTabbar===true){ wx.switchTab({ url:to }) }else{ wx.navigateTo({ url: to }) } clearTimeout(time); },2000)}
還有一種情況就是我們開(kāi)始將數(shù)據(jù)返回給后端,這個(gè)時(shí)候最好給用戶(hù)一個(gè)加載中的提示,而這個(gè)提示可以使用wx.showLoadding
來(lái)做:
// 提示用戶(hù)數(shù)據(jù)保存中startOperating:function(info){ wx.showLoading({ title:info, mask:true }) }
當(dāng)后端返回結(jié)果后。則將加載框進(jìn)行隱藏:
stopOperating:function(){ wx.hideLoading(); }
登錄類(lèi)問(wèn)題
微信小程序不支持session,這個(gè)是前提,所以我們沒(méi)辦法在后端使用session來(lái)進(jìn)行用戶(hù)身份的區(qū)分。我的解決思路是這樣的,在項(xiàng)目的入口文件app.js中的onLaunch
函數(shù)中,即在用戶(hù)開(kāi)啟小程序后調(diào)用wx.login()
函數(shù)獲取用戶(hù)的唯一微信標(biāo)志code,接著將該標(biāo)志傳回后端,調(diào)用微信的統(tǒng)一API,獲取用戶(hù)在該微信小程序中的唯一標(biāo)識(shí),注意,即使是同一個(gè)用戶(hù),在不同的微信小程序中標(biāo)識(shí)也是不一樣的。
獲取該標(biāo)識(shí)后,后端調(diào)用緩存將該標(biāo)識(shí)緩存起來(lái),時(shí)間也不用擔(dān)心,由于寫(xiě)在app.js中,所以每次啟動(dòng)都會(huì)去詢(xún)問(wèn)后端,后端做相應(yīng)的登錄更新處理就可以了。
實(shí)際前端代碼
// app.jsAPP({ onLaunch:function(){ this.login(); }, login:function(){ // 我喜歡把域名保存在globalData中,這樣即使后期修改了域名,也不用到每個(gè)文件中去改 var that=this; wx.login({ success:function(res){ // 這里獲取標(biāo)識(shí) var code=res.code; // 將該標(biāo)識(shí)傳遞給后端 wx.request({ url:that.globalData.url+"/home/login/login?code="+code, success:function(res){ // 假設(shè)后端返回一個(gè)session_key作為改用戶(hù)的唯一標(biāo)識(shí),所有請(qǐng)求都需要攜帶該參數(shù) var session_key=res.data.session_key; // 調(diào)用全局緩存來(lái)保存該值 wx.setStorageSync('session_key', session_key); }, fail:function(error){ // 寫(xiě)這么一個(gè)函數(shù),是幫助自己后期出現(xiàn)問(wèn)題時(shí)可以進(jìn)行修復(fù) console.error("調(diào)用微信登錄接口錯(cuò)誤"); console.log(error); } }) } }) }, globalData:{ url:"http://yourdomain.com" }})
實(shí)際后端代碼
class LoginController extends Controller{ // 你的小程序唯一標(biāo)識(shí) private $appid=""; private $secrect=""; public function login(){ // 獲取前端傳遞過(guò)來(lái)的code $code=$_GET['code']; // 調(diào)用微信的統(tǒng)一API $baseUrl="https://api.weixin.qq.com/sns/jscode2session?appid={$this->appid}&secret={$this->secrect}&js_code={$code}&grant_type=authorization_code"; // 微信返回結(jié)果處理 $result=curl_get_contents($baseUrl); $user=json_decode($result,true); if($user['error_code']){ // 這里是調(diào)用錯(cuò)誤的函數(shù),如何解決看你自己的業(yè)務(wù)邏輯 exit(); } // 該用戶(hù)在你小程序中的唯一標(biāo)識(shí) $openid=$user['openid']; // 判斷是新用戶(hù)還是老用戶(hù) $userInfo=M('User')->where(array('openid'=>$openid))->find(); if($userInfo){ // 老用戶(hù) $user_id=$userInfo['id']; $session_key=$this->getSessionKey($openid,$user_id); }else{ // 新用戶(hù)則將其保存進(jìn)數(shù)據(jù)庫(kù)中 $user_id=M("User")->add(array('openid'=>$openid)); $session_key=$this->getSessionKey($openid,$user_id); } // 緩存起來(lái),至于有效期最好長(zhǎng)一點(diǎn),以防止用戶(hù)在使用過(guò)程中突然不能訪問(wèn)數(shù)據(jù),我這里是使用tp框架的S()函數(shù)進(jìn)行存儲(chǔ)的 S($session_key,$user_id); // 以后只需要用戶(hù)傳遞過(guò)來(lái)$session_key就可以根據(jù)緩存獲取用戶(hù)身份了 // 將結(jié)果發(fā)送給前端 $this->ajaxReturn(array( 'session_key'=>$session_key )); } // 生成用戶(hù)的session_key private function getSessionKey($openid,$user_id){ $key="可以說(shuō)是你的密鑰吧"; return hash("md5",$key.$openid.$user_id); }}
當(dāng)然這里我只是保存了$user_id,如果你需要更多信息可以考慮使用redis,memcached等進(jìn)行長(zhǎng)期緩存,反正每次產(chǎn)生的$session_key都是一樣的。
Session_key使用例子
上面我們獲取了session_key并在前后端進(jìn)行了保存,接下來(lái)就是如何使用該session_key了。
后端驗(yàn)證
關(guān)于CommonContrller的原理請(qǐng)看之前的一篇博客:tp框架的RBAC實(shí)現(xiàn)
class CommonController extends Controller{ protected $user_id; public function ___initialize(){ // 對(duì)用戶(hù)的session_key進(jìn)行驗(yàn)證 $session_key=I("session_key"); $user_id=S($session_key); if(!$user_id){ // 該$session_key失效或者不合法 $this->ajaxReturn(array('result'=>"請(qǐng)退出小程序重新登錄"));exit(); } $this->user_id=$user_id; }}
接著假設(shè)下面是你真正想要訪問(wèn)的方法
class IndexController extends CommonController{ public function(){ // 假設(shè)這里你需要獲取當(dāng)前用戶(hù)的id,只需要直接調(diào)用父類(lèi)中的屬性就可以了 $user_id=$this->user_id; }}
上面我們就借用了我們生成的session_key配合上緩存模擬了session的驗(yàn)證機(jī)制,希望對(duì)你們有用。
前端實(shí)現(xiàn)
getData:function(){ // 從緩存中獲取session_key,并將其傳遞給后端,做用戶(hù)身份的確認(rèn) var session_key=wx.getStorageSync('session_key'); wx.request({ url:app.globalData.url+"/home/index/index?session_key="+session_key, success:function(res){ // } })}
前置頁(yè)面做優(yōu)化
上面我們是在app.js的onLaunch
中直接調(diào)用登錄函數(shù),但是這樣卻存在一個(gè)問(wèn)題,那就是登錄沒(méi)有完成,就跳轉(zhuǎn)到入口的page中,接著由于session_key還沒(méi)有生成,導(dǎo)致頁(yè)面數(shù)據(jù)請(qǐng)求失敗。我當(dāng)時(shí)就是遇到了這個(gè)問(wèn)題,所以我把入口的page
設(shè)置成了前置頁(yè)面,并在前置頁(yè)面中添加了下面的函數(shù):
onLoad: function (options) { var time=setInterval(function(){ var session_key=wx.getStorageSync('session_key'); // 只有當(dāng)session_key存在時(shí),才跳轉(zhuǎn)到首頁(yè)去,保證請(qǐng)求數(shù)據(jù)的有效性,否則就在前置頁(yè)面暫留一會(huì) if(session_key.length>5){ wx.switchTab({ url:"/pages/index/index" }) clearInterval(time); } },1000);}
希望本文所述對(duì)大家微信小程序開(kāi)發(fā)有所幫助。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注