微信小程序:期刊切换,代码重构,缓存Storage,setStorageSync,wx:if【诗书画唱】


目录:
例子1:根据index判断是第一期还是最后一期
classicModel中的isFirst和isLatest方法,缓存(Storage)最新期刊号_setLatest方法


首先的话,我们点击前一期翻页的“右耳朵”图片的时候,要触发一个可以传含有特定的参数值的url路径到后台的getPrev的函数,之后后台代码根据url从数据库查到特定的参数值为SQL语句中的where后面的筛选条件的后台数据,之后前台获取后台数据。getPrev的函数也是写在models文件夹下的js文件中的。封装,要复用,在别处要多次重复调用,进行了代码重构的代码一般都写在models文件夹下的js文件中。
用setStorageSync来把数据缓存到自己命名的变量名中,点"调试器"后,可以在Storage查看自己是否缓存成功,可以查看Key(键,变量名),Vue(值,数据的具体内容),Type(数据类型)
清除缓存的方法(不清的话,基本重启等候都会一直存在缓存)
一般是在models文件夹下的classic.js中声明和调用关于wx.setStrorageSync等缓存的代码的
为了让使用者先看到最新的一期,所以进行如下的设计:这里左边的翻页“耳朵”是"翻到下一页(更新的一期)",这里右边的翻页“耳朵”是"翻到上一页(往前的一期)"
例子2:实现期刊切换后一期效果

图示中的往前翻,和往后翻的代码基本都是一样的,因此可以进行代码重构,封装
代码等等要尽可能的进行封装,方便后期的维护,修改一个封装的部分就可以同时修改调用封装代码的部分
这里就是对代码进行了封装
例子3:对封装代码进行优化,把一些callback改成success,方便对ajax获取到的数据进行处理

ajax获取到的数据就是在success中进行处理
例子4:解决model中的回调函数处理bug和大图片显示bug

子组件都要用的大图片路径的部分,其实要写在关于Behavior的文件夹下的js文件中(因为data.image的部分是多个子组件都要用的部分,所以可以可以在Behavior中声明个base_img的属性名,data.image的部分就是base_img的属性名对应的值。
下面用了解构语法,代码变得更简洁了,在import的同时,就给一个变量进行了赋值,之后就直接调用这个变量就可以了
注意这里的base_img对应的内容写错了,如果不改过来,会导致bug。很多bug都可能是因为变量名写错或有些代码没有注释
用wx:if进行判断有时可以解决渲染层网络层出错,防止加载图片之间,界面就被渲染出来了。用wx:if进行判断是否加载图片为空,不为空,说明图片不为空,那么就执行判断里面的代码
例子5:代码部分和讲义
现在我们是只实现了电影组件的部分,音乐等组件的部分以后再做。
要改动的文件:
components/classic/movie/index.wxml
components/classic/classic_beh.js
models/classic.js
pages/classic/index.js
pages/classic/index.wxml

例子1:根据index判断是第一期还是最后一期
classicModel中的isFirst和isLatest方法,缓存(Storage)最新期刊号_setLatest方法


首先的话,我们点击前一期翻页的“右耳朵”图片的时候,要触发一个可以传含有特定的参数值的url路径到后台的getPrev的函数,之后后台代码根据url从数据库查到特定的参数值为SQL语句中的where后面的筛选条件的后台数据,之后前台获取后台数据。getPrev的函数也是写在models文件夹下的js文件中的。封装,要复用,在别处要多次重复调用,进行了代码重构的代码一般都写在models文件夹下的js文件中。



Q:如果出现"渲染层网络层错误",出现image的字眼等等,如何解决
A:查看是不是图片的路径出错,修改下关于图片的代码




值得注意的是,改后的代码中关于组件的图片路径的data.image的部分,其实要写在关于Behavior的文件夹下的js文件中(因为data.image的部分是多个子组件都要用的部分,所以可以可以在Behavior中声明个base_img的属性名,data.image的部分就是base_img的属性名对应的值。

用setStorageSync来把数据缓存到自己命名的变量名中,点"调试器"后,可以在Storage查看自己是否缓存成功,可以查看Key(键,变量名),Vue(值,数据的具体内容),Type(数据类型)

清除缓存的方法(不清的话,基本重启等候都会一直存在缓存)


一般是在models文件夹下的classic.js中声明和调用关于wx.setStrorageSync等缓存的代码的




为了让使用者先看到最新的一期,所以进行如下的设计:这里左边的翻页“耳朵”是"翻到下一页(更新的一期)",这里右边的翻页“耳朵”是"翻到上一页(往前的一期)"

例子2:实现期刊切换后一期效果

代码等等要尽可能的进行封装,方便后期的维护,修改一个封装的部分就可以同时修改调用封装代码的部分



例子3:对封装代码进行优化,把一些callback改成success,方便对ajax获取到的数据进行处理


ajax获取到的数据就是在success中进行处理



例子4:解决model中的回调函数处理bug和大图片显示bug

子组件都要用的大图片路径的部分,其实要写在关于Behavior的文件夹下的js文件中(因为data.image的部分是多个子组件都要用的部分,所以可以可以在Behavior中声明个base_img的属性名,data.image的部分就是base_img的属性名对应的值。



下面用了解构语法,代码变得更简洁了,在import的同时,就给一个变量进行了赋值,之后就直接调用这个变量就可以了





用wx:if进行判断有时可以解决渲染层网络层出错,防止加载图片之间,界面就被渲染出来了。用wx:if进行判断是否加载图片为空,不为空,说明图片不为空,那么就执行判断里面的代码

例子5:代码部分和讲义
准备:后台代码处理
一、创建新项目和页面
二、app.json配置导航栏
三、定义和使用点赞组件
"四、classic在生命周期函数中请求后台数据
设置-项目设置-勾选不校验..."
五、封装Http工具类。
六、将classic页面的数据传递到like组件中(父组件传数据到子组件)
七、实现movie组件
八、like组件传递数据到classic页面(子传父实现自定义事件)
"九、epsoide组件(组件的生命周期函数以及data和properties定义数据的区别)
data和properties会被合并成同一个对象,如果有同名属性,会使用properties中定义的属性
期刊号补零(observer函数)"
"十、初步完成导航组件
获取数据:title,isFirst和isLatest
自定义导航事件onLeft,onRight
禁用左翻页和右翻页"
十一、初步实现music组件和essay组件
十二、提取组件的公共部分(组件的行为Behavior实现多继承)
"十三、初步实现期刊切换前一期效果(后台getClassic实现)
classic页面的onPrev"
"十四、根据index判断是第一期还是最后一期
classicModel中的isFirst和isLatest方法,缓存(Storage)最新期刊号_setLatest方法"
"十五、实现期刊切换后一期效果
classic页面的onNext
classicModel中的getNext和getPrev代码重构
classic页面的onPrev和onNext代码重构"
十六、期刊数据数据缓存实现,(model中的回调函数处理bug和大图片显示bug)
十七、缓存数据以后无法显示更新后的点赞次数和状态(后台代码getClassic扩展)

要改动的文件:

<!--components/classic/movie/index.wxml-->
<view class="container">
<image src="{{base_img + img}}" class="img"/>
<image src="{{icon}}" class="tag"/>
<text class="content">{{content}}</text>
</view>

//components/classic/classic_beh.js
import config from '../../config'
export default Behavior({
properties: {
img: String,
content: String
}
//music等子组件要共用的base_img部分 START
,
data: {
base_img: config.img_url
}
//music等子组件要共用的base_img部分 END
})
现在我们是只实现了电影组件的部分,音乐等组件的部分以后再做。


//models/classic.js
import Http from '../utils/http.js'
import config from '../config.js'
export default class ClassicModel extends Http{
//获取最新的期刊数据
getLatest(cb){
this.ajax({
url: `${config.base_url}getLatest`,
// callback: data => {
// cb(data);
// //自己写的代码 START
// console.log("models/classic.js中打印的数据:",data)
// //自己写的代码 END
// }
success: data => {
this._setLastedIndex(data.index)
cb(data)
// //自己写的代码 START
console.log("models/classic.js中打印的数据:",data)
// //自己写的代码 END
}
})
}
//关于数据库和页面的点赞数同步更新的部分 START
//更新点赞状态
like(data){
this.ajax({
url: `${config.base_url}like`,
data
})
}
//关于数据库和页面的点赞数同步更新的部分 END
//关于翻页更新对应后台数据库数据功能的部分 START
getClassic(index,status,callback) {
this.ajax({
url: `${config.base_url}getClassic`,
data: {
index,
status
},
success: res => {
callback(res)
}
})
}
//将index缓存到内存中
_setLastedIndex(index){
wx.setStorageSync('latestIndex', index)
}
//获取缓存的最新期刊号
_getLastedIndex(){
return wx.getStorageSync('latestIndex')
}
//判断当前的期刊是否是第一期
isFirst(index){
return index === 1
}
//判断当前的期刊是否是最后一期
isLatest(index){
let lastedIndex = this._getLastedIndex()
return index === lastedIndex
}
//关于翻页更新对应后台数据库数据功能的部分 END
}


// pages/classic/index.js
import ClassicModel from '../../models/classic.js'
//关于数据库和页面的点赞数同步更新的部分 START
import config from '../../config.js'
//关于数据库和页面的点赞数同步更新的部分 END
const classicModel = new ClassicModel()
Page({
/**
* 页面的初始数据
*/
// data: {
// classicData: null
// },
data: {
classicData: null,
isFirst: false,
isLatest: true
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
classicModel.getLatest(data => {
console.log("pages/classic/index.js中打印的数据:",data)
//关于数据库和页面的点赞数同步更新的部分 START
// console.log(data)
//修改image属性的内容:
// data.image = config.img_url + data.image
//关于数据库和页面的点赞数同步更新的部分 END
//更新数据
this.setData({
classicData: data
})
})
},
//关于数据库和页面的点赞数同步更新的部分 START
onLike(e){
console.log("诗书画唱提醒你,点击后触发了pages/classic/index.js中的onlike方法")
//更新点赞的状态
console.log("点赞数",e.detail.nums)
classicModel.like({
status: e.detail.state,
index: this.data.classicData.index,
nums: e.detail.nums
})
},
//关于数据库和页面的点赞数同步更新的部分 END
//导航栏的左翻页和右翻页部分 START
onNext(){
console.log('获取下一期的期刊数据')
this._updateClassic('next')
},
onPrev(){
console.log('获取上一期的期刊数据')
this._updateClassic('prev')
},
_updateClassic(nextOrPrev){
//获取当前的期刊号
let index = this.data.classicData.index
classicModel.getClassic(index,nextOrPrev,data => {
//更新数据
this.setData({
classicData: data,
isFirst: classicModel.isFirst(data.index),
isLatest: classicModel.isLatest(data.index)
})
})
},
//导航栏的左翻页和右翻页部分 END
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})


<!--pages/classic/index.wxml-->
<view class="container">
<view class="header">
<cmp-epsoide class="epsoide" index="{{classicData.index}}"></cmp-epsoide>
<!-- 下面的话就是调用了点赞的组件: -->
<cmp-like count="{{classicData.fav_nums}}" like="{{classicData.like_status}}"
bind:myLike="onLike"></cmp-like>
</view>
<cmp-movie wx:if="{{classicData.image}}" content="{{classicData.content}}" img="{{classicData.image}}"></cmp-movie>
<cmp-navi class="navi" title="{{classicData.title}}" isFirst="{{isFirst}}"
isLatest="{{isLatest}}" bind:myLeft="onNext"
bind:myRight="onPrev"></cmp-navi>
</view>

运行效果





