小程序学习--如何利用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}

代码的想法和讲解都写在注释中,在小程序中,写这种缓存机制很麻烦,关键在于自己想不想在优化方面花更大的心思

猜你喜欢

转载自blog.csdn.net/zhangzeshan/article/details/83987884