1. 程式人生 > >小程式學習--如何利用storage快取機制(小程式快取功能)

小程式學習--如何利用storage快取機制(小程式快取功能)

小程式中一個切換期刊的業務,每次切換的時候,都需要向伺服器傳送請求,顯得很麻煩,

所以才去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}

程式碼的想法和講解都寫在註釋中,在小程式中,寫這種快取機制很麻煩,關鍵在於自己想不想在優化方面花更大的心思