1. 程式人生 > >微信小程式入門到實戰(五)

微信小程式入門到實戰(五)

快取

快取的作用是為了加快資料的訪問,小程式裡面可以設定快取(本地),設定快取後,如果沒有手動清除快取的話,就會一直存在。大小不能超過10M。資料優先。

  • 設定快取

wx.setStorageSync('key','value'):同步
wx.setStorage({key:'key',data:'value'}):非同步

wx.setStorageSync('icessun','2018/2/14')   // 同步設定快取

wx.setStorage({key:'跳一跳',data:'666'})   // 非同步設定快取

同步設定快取

同步設定快取,快取值可以為一個字串,也可以為一個物件,當第一個引數值相同的時候,後面的會覆蓋前面的。非同步也一樣。

  wx.setStorageSync('key',{
      game: "跳一跳",
      gold: "666"
    })

同步設定快取

非同步設定快取,裡面的屬性是固定的,接收一個物件為引數,也就是說,當你不使用key/data作為引數名字時,就會報錯:

setStorage:fail parameter error: parameter.key should be String instead of Undefined;

非同步設定快取

  • 獲取快取
    獲取快取的方法很簡單,把對應設定快取的set變為get就行。
    wx.getStorageSync('key'):同步 直接返回獲取到的值
    wx.getStorage({key:'key',callback})
    :非同步 通過回撥函式返回獲取的值
wx.setStorageSync('key', {
      game: "跳一跳",
      gold: "666"
    })

    var a=wx.getStorageSync('key');
    console.log(a);   //     {game: "跳一跳", gold: "666" }
上面是同步獲取快取值的方法,直接通過變數去接收穫取到的快取值,如果是非同步的方法獲取快取值,那麼需要在回撥函式裡面取得快取值;同步和非同步兩種方法中的`key`是必須要傳入的,否者不知道獲取的具體快取值。
    wx.
setStorage({ key: "跳一跳", data: "666" }) var a = wx.getStorage({ key:'跳一跳', success: function (res) { console.log(res.data); console.log(res); } });
![非同步獲取快取值](http://upload-images.jianshu.io/upload_images/1811036-0801ea1bfde83c94.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  • 清除快取
    清除快取的方法有兩種,clearStorageremoveStorage,每一種都有同步和非同步之分:
// 從本地快取中非同步移除指定 key 
wx.removeStorage({
  key: 'key',
  success: function(res) {
    console.log(res.data)
  } 
})

// 同步移除指定 key 
try {
  wx.removeStorageSync('key')
} catch (e) {
  // Do something when catch error
}

//清理本地資料快取
wx.clearStorage()

// 同步清理本地資料快取
try {
    wx.clearStorageSync()
} catch(e) {
  // Do something when catch error
}

前面說過,快取是一直存在的,只能通過呼叫這個方法去清除快取。

快取實踐

  • 文章收藏實現
    文章收藏快取

那麼用快取,怎麼樣實現呢?首先是文章數量很多,怎麼樣知道是那篇文章被收藏了,也就是說文章與快取資料怎麼樣一一對應,同時也說明快取資料的儲存方式?收藏的圖示怎麼樣容易切換顯示(這個問題,前面的文章已經說了解決辦法)?

收藏和未收藏,是兩個不同的狀態,那麼就會想到布林值去實現;與文章的一一對應關係,那麼會想到使用一個物件去操作,key 表示對應的文章,value表示收藏的狀態。

postCollected={
    0:'ture',    // 文章的id:是否被收藏(true/false)
    1:'false'
     ...
}

在文章載入的時候,先要獲取一下快取,看是否存在收藏記錄,然後進行狀態的判斷,彈框提示。

var postData = require('相對路徑') // 本地資料
onLoad:function(options){
    var postId = options.id;
    var  postData = postData.postList[postId];  // 本地資料中資料輸出,對應頁面的資料
    this.setData({
       postData:postData,
       postId:postId
   })

   var postsCollected= wx.getStorageSync('icessun');  // 讀取快取
   if(postsCollected){    // 狀態判斷
             var postStor = postsCollected[postId];
              this.setData({
                    collected:postStor 
               })
    }else{
           var  postsCollected = {};  // 把快取物件預設為空,防止後面訪問物件屬性出錯
            postsCollected[postId] = false;
            wx.setStorageSync('icessun',postsCollected);
    }
}

其中的options.id獲取的是前一個頁面傳遞過來的引數(前一篇文章末尾已經說過):文章ID。然後判斷快取中頁面是否被收藏,把這個狀態值設定給wxml,進而控制圖片的顯示。

<!--collected 狀態變數 在js檔案裡面控制真假  -->
      <image catchtap='onCollectionTap' wx:if='{{collected}}' src='/images/icon/collection.png'></image>
      <image catchtap='onCollectionTap' wx:else src='/images/icon/collection-anti.png'></image>

頁面上的資料繫結
實現了快取文章收藏的狀態,怎麼樣在收藏和未收藏之間來回切換呢?

 onCollectionTap: function (event) {
    var postsStorage = wx.getStorageSync('icessun');
    var postStor = postsStorage[this.data.currentPostId]; // 根據文章的id,獲取收藏的狀態
    postStor = !postStor;  // 收藏與未收藏之間的切換

    postsStorage[this.data.currentPostId] = postStor;
    this.showModal(postsStorage, postStor)
  }

非同步儲存快取

 onCollectionTap: function (event) {
    this.getPostCollectedAsy();
  },
 // 非同步方法快取
  getPostCollectedAsy: function () {
    var that = this;
    wx.getStorage({  // 非同步方法的使用
      key: 'icessun',
      success: function (res) {
        var postCollected = res.data;
        var postsColl = postCollected[that.data.currentPostId];
        postsColl = !postsColl;
        postCollected[that.data.currentPostId] = postsColl;
        that.showToast(postCollected, postsColl);
      },
    })
  }

非同步不會阻塞UI,但還是需要根據實際業務需求來,業務需要解耦的話,那麼就使用非同步,一般都推薦使用同步。脫離業務談同步和非同步,意義不大。

在收藏圖片上面加一個按鈕,點選的時候,彈出一個提示框:是否收藏。跟新收藏狀態就行。

showModal: function (postsStorage, postStor) {
    var _this = this;  // 注意this的指向
    wx.showModal({
      title: ' ',
      content: postStor ? '收藏該文章?' : '取消收藏該文章?',
      showCancel: 'true',
      cancelText: '取消',
      cancelColor: '#333',
      confirmText: '確認',
      confirmColor: '#405f80',
      success: function (res) {
        if (res.confirm) {
          wx.setStorageSync('icessun', postsStorage);
          _this.setData({
            collected: postStor
          })
        }
      }
    })
  }

this指向的是函式呼叫的上下文環境,success函式裡面的this指向showModal,但裡面沒有setData方法,this執行被改變了。所以要在showModal函式裡面先把this暫存一下,保持this執行的不變。

介面互動,兩種方法showToastshowModal,前者不用操作就會消失,後者需要操作才會消失。
showToast效果
showModal效果

showToast: function (postsStorage, postStor) {
    var _this = this;
    // 先根據快取設定圖示,然後在提示文字 注意引數的傳遞 也要注意this的指向
    wx.setStorageSync('icessun', postsStorage);
    _this.setData({
      collected: postStor
    });
    wx.showToast({
      title: postStor ? '收藏成功' : '取消成功',
      duration: 1000,
      icon: "success"
    })
  }
  • 文章閱讀數增加

使用快取去記錄文章的閱讀數量(本地資料)。

因為微信小程式核心是一個響應的資料繫結系統,整個系統分為兩塊檢視層(View)邏輯層(App Service),框架可以讓資料與檢視非常簡單地保持同步。當做資料修改的時候,只需要在邏輯層修改資料,檢視層就會做相應的更新。

思考:類似與上一個文章收藏,也是使用一個物件把文章ID和閱讀量進行一一對應。頁面資料的更改,都是在該頁面的Data屬性裡面進行;進入了頁面詳情頁,那麼該頁面的瀏覽量就增加1;

onLoad: function (options) {
// 頁面載入的時候先訪問快取
    var viewDatas = wx.getStorageSync("viewData");
    for (var i = 0; i < postData.postList.length; i++) {
      if (viewDatas[i]) {
        postData.postList[i].view_num = viewDatas[i]
      }
    }

    this.setData({
      // 獲取匯入的模版資料,設定到頁面data資料裡面,供wxml頁面使用
      post_key: postData.postList
    });
  },

  newsdetail: function (event) {
    // 當前點選事件觸發的元素身上設定的postid,訪問自定義屬性
    var postid = event.currentTarget.dataset.postid;
    var viewDatas = wx.getStorageSync("viewData");
    if (viewDatas) {
      if(viewDatas[postid]){
        viewDatas[postid] = viewDatas[postid] + 1;
      }else{
        viewDatas[postid]=1;
      }
      postData.postList[postid].view_num = viewDatas[postid];
      this.setData({
        post_key: postData.postList
      });
      wx.setStorageSync("viewData", viewDatas);
    }
    else {
      var viewDatas = {};
      viewDatas[postid] = 1;
      postData.postList[postid].view_num = 1;
      this.setData({
        post_key: postData.postList
      });
      wx.setStorageSync("viewData", viewDatas);
    }

    wx.navigateTo({
      url: 'post-detail/post-detail?id=' + postid
    });
  }

首先,頁面初始化的時候,就應該讀取一下快取;根據快取與文章是一一對應的關係,使用迴圈去操作。注意一點的是,我們應該判斷viewDatas[i]的真假,而不是wx.getStorageSync("viewData")的真假。然後是詳情頁面的點選,和前面說的一樣,應該判斷viewDatas[i]的真假,否者會出現,第一次點選是好的,然後就出現瀏覽量為null的情況,是因為點選一個沒有在快取中出現過的文章,其viewDatas[postid]undefined,與數字1相加出現NaN,進而出現null。初始化的時候,要把快取置空var viewDatas = {};,防止後面訪問出現錯誤。

if(viewDatas[postid]){
        viewDatas[postid] = viewDatas[postid] + 1;
 }else{
        viewDatas[postid]=1;
      }