小程式學習--如何利用storage快取機制(小程式快取功能)
阿新 • • 發佈:2018-11-13
小程式中一個切換期刊的業務,每次切換的時候,都需要向伺服器傳送請求,顯得很麻煩,
所以才去storage的機制,在編譯過程中就載入好資料存放到快取中,這樣每次切換期刊的時候,不用再次傳送請求,完成優化
開啟開發工具的偵錯程式,選擇network,每次切換的時候,只請求新期刊的點贊狀態,而其他資訊不再請求
每一期的期刊只請求了一次,其他都是點贊狀態的請求也就是favor
接下來看如何實現:
首先先看下page頁面的程式碼:
<!-- 資料渲染 從對應頁面的js檔案進行拿值 classic是從js中自定義的 可從控制檯的APPData檢視--> <view class="container"> <view class='header'> <!-- 年月和排序 --> <v-episode class="episode" index="{{classic.index}}"/> <view class="like-container"> <!-- 點贊 --> <v-like class="like" bind:like="onLike" like="{{likeStatus}}" count="{{likeCount}}"/> <!-- 分享按鈕 --> <v-button class="share-btn" open-type="share"> <image class="share" slot="img" src="/images/icon/share.png"/> </v-button> </view> </view> <!-- 圖片和題目還有分類名 電影 音樂 句子--> <!-- hidden會讓detached函式失效 所以音樂元件要換成wx.if --> <v-movie hidden="{{classic.type!=100}}" img="{{classic.image}}" content="{{classic.content}}"/> <v-music wx:if="{{classic.type==200}}" src="{{classic.url}}" img="{{classic.image}}" content="{{classic.content}}"/> <v-essay hidden="{{classic.type!=300}}" img="{{classic.image}}" content="{{classic.content}}"/> <!-- 左右切換標題 --> <v-navi bind:left="onNext" bind:right="onPrevious" class="navi" title="{{classic.title}}" first="{{first}}" latest="{{latest}}"/> <!-- first和latest都是從class.js中進行初始化 --> </view>
切換期刊的是 v-navi 這個元件,接下來看這個頁面的js檔案:
/** * 匯入HTTP */ // import{HTTP} from '../../util/http.js' // let http = new HTTP()//例項化HTTP /** * 匯入ClassicModel */ import{ClassicModel} from '../../models/classic.js' let classicModel = new ClassicModel()//例項化 /** * 匯入LikeModel */ import{LikeModel} from '../../models/like.js' let likeModel = new LikeModel();//例項化 Page({ /** * 頁面的初始資料 */ data: { //定義的三個初始化的值拿到setData中呼叫 classic:null, latest:true,//最新一期初始化 first:false,//最早一期初始化 //以下兩個變數單獨更新 likeCount:0, likeStatus:false }, /** * 生命週期函式--監聽頁面載入 */ onLoad: function (options) { //呼叫classicModel中的js方法getLatest //使用storage的快取功能儲存 將classic的index寫入到快取中--->models的class.js classicModel.getLatest((res) => { this.setData({//資料繫結和資料更新 classic: res,//要在data中標識下----前端渲染資料值為 classic.欄位名 //...res,//前端渲染的資料值為欄位名 //更新 likeCount:res.fav_nums, likeStatus:res.like_status }) }) }, onLike:function(event){ // console.log(event); let behavior = event.detail.behavior;//獲取打印出來的behavior值 likeModel.like(behavior, this.data.classic.id, this.data.classic.type )//第二個引數和第三個引數可以從上面的classic中獲得 }, //左鍵--呼叫classicModel中的js方法getNext onNext: function (event){ this._updateClassic('next') }, //右鍵--呼叫classicModel中的js方法getPrevious onPrevious: function (event) { this._updateClassic('previous') }, //左右鍵能否點選呼叫私有方法--models下的classic.js的getClassic方法 _updateClassic: function (nextOrPrevious){ //獲取index index 存在與data中的classic const index = this.data.classic.index;//const代替let let代替var classicModel.getClassic(index, nextOrPrevious, (res) => { this._getLikeStatus(res.id,res.type) //更新資料 this.setData({ classic: res, //動態改變左右鍵的值 latest: classicModel.isLatest(res.index), first: classicModel.isFirst(res.index) }) }) }, //呼叫models中的like.js的方法getClassicLikeStatus _getLikeStatus:function(artID,category){ likeModel.getClassicLikeStatus(artID,category,(res)=>{ this.setData({ likeCount:res.fav_nums, likeStatus:res.like_status }) }) } })
這個js檔案中引入三個檔案:
首先第一個,是util下的http.js
//進行wx.request的封裝 //匯入 config import {config} from '../config.js' // import { config as config1} from '/config.js' 重新命名匯入 // import { config , fun1 ,fun2} from '/config.js' 匯入多個函式 //定義錯誤碼 const tips = { 1:'抱歉,出現了錯誤',//設定預設錯誤 1005:'不正確的開發者key', 3000:'期刊不存在' } class HTTP{ request(params){ if(!params.method){ params.method = "GET" } //url,data,method(預設為get) wx.request({ url: config.api_base_url+params.url, method:params.method, data:params.data, header:{ 'content-type':'application/json', 'appkey':config.appkey }, success:(res)=>{ let code = res.statusCode.toString();//將code的值轉換為字串 if (code.startsWith('2')){ params.success && params.success(res.data);//呼叫回撥函式,將res傳遞進來 }else{ //伺服器異常 //呼叫私有方法 let error_code = res.data.error_code; this._show_error(error_code); } }, fail:(err)=>{//api呼叫失敗 this._show_error(1); } }) } //自定義私有方法 加下劃線區分 _show_error(error_code){ if (!error_code) { error_code = 1; } const tip = tips[error_code] wx.showToast({ title: tip ? tip : tips[1],//呼叫上面定義的錯誤資訊 icon: 'none', duration: 2000 }) } } //輸出這個類 export{HTTP}
第二個檔案:是models下的classic.js檔案 這個檔案主要是寫當前頁面的業務邏輯:
import {
HTTP
} from '../util/http.js'//匯入
//繼承類
//本檔案編寫方法進行請求資料,之後方法名拿到頁面的js進行呼叫
//如方法:getLatest,getPrevious
class ClassicModel extends HTTP{
//請求內容
getLatest(sCallback){
this.request({
url: 'classic/latest',
success: (res) => {
sCallback(res)
this._setLatestIndex(res.index)
let key = this._getkey(res.index)
wx.setStorageSync(key, res)
}
})
}
//請求前一篇內容和請求後一篇內容(合併在一起)
//額外引數index(文件中獲取),定義回撥函式作為引數
getClassic(index,nextOrPrevious,sCallback){
//快取中尋找 找不到就傳送請求然後寫入到快取中 找得到 就不用傳送請求
//確定key
//如果是next就+1 否則就-1
let key = nextOrPrevious == 'next' ?
this._getkey(index+1) : this._getkey(index-1)
let classic = wx.getStorageSync(key)
//判斷classic是否存在key
if(!classic){
this.request({
url: `classic/${index}/${nextOrPrevious}`,//
success: (res) => {
wx.setStorageSync(this._getkey(res.index),res);//寫入快取
sCallback(res);
}
})
}else{
sCallback(classic)
}
}
//判斷是否最早一期
isFirst(index){
return index == 1 ? true:false
}
//判斷是否最新一期
isLatest(index) {
let latestIndex = this._getLatestIndex()
return latestIndex == index ? true : false
}
//獲取我喜歡的
getMyFavor(success){
const params = {
url:'classic/favor',
success:success
}
this.request(params)
}
//設定私有方法將classic的index放到快取中
_setLatestIndex(index){
wx.setStorageSync('latest', index)//同步寫入快取
//非同步寫入是去掉Sync
}
//讀取快取中的index
_getLatestIndex(){
let index = wx.getStorageSync('latest')//同步讀取快取
return index
}
//私有方法產生key 讀快取時候獲取key值
_getkey(index){
let key = 'classic-'+index;
return key
}
}
export { ClassicModel}
第三個檔案是models下的like.js 這個檔案是寫點贊狀態的業務邏輯
import{HTTP} from '../util/http.js'//匯入
class LikeModel extends HTTP{
//like方法呼叫request進行資料的提交
like(behavior,artID,category) {
//傳參 behavior 還有文件中的引數 art_id和category(type) 不用type是因為關鍵字
let url = behavior =='like'?'like':'like/cancel';
this.request({
url:url,//URL賦值
method:'POST',
data:{
art_id:artID,//引數賦值
type:category
}
})
}
getClassicLikeStatus(artID,category,sCallback){
this.request({
url:'classic/'+ category +'/'+ artID +'/favor' ,
success:sCallback
})
}
}
export{LikeModel}
程式碼的想法和講解都寫在註釋中,在小程式中,寫這種快取機制很麻煩,關鍵在於自己想不想在優化方面花更大的心思