前言
大一暑假在原版的基础上完成了矿大微学工小程序的重做,期间遇到了很多的困难和疑惑,同时也找到了许多问题的解决办法,为方便今后查阅,将其记录下来,同时也希望大家指正错误。
异步问题
微信小程序提供的API接口属于异步行为,即当调用该接口时,会额外开启一个新的线程,和原来的并行执行,这样可能会出现一个问题:还未从该API中取得所需要的值时后续操作就已经执行,导致失败,
这在下面接口封装时就曾经困住了我好长时间。
解决办法是将后续操作全部放入api的回调函数success中,这样就保证了该API调用完毕并获取到参数后才会执行后续操作。
wx.getStorage({
key: '',
success:function(res){
wx.getStorage({
key: '',
success: function(res) {
that.setData({
stu_id: res.data
})
console.log(res.data)
},
})
}
})
函数封装
通过该项目,我对微信小程序的目录结构有了更深入的认识,尤其是对全局文件app.js有了更深入的体会,通过他能进一步提高了代码的利用效率。
在该项目中,我选择了将wx.request封装起来,每次需要的时候调用,这的确方便了许多,下面是具体的操作:
第一步:在util.js中完成函数:
var apiHost ='https//服务器前半部分统一的地址'
function Request(url, method, callback,data='') {
var header = {
'content-type': 'application/json'
}
wx.getStorage({
key: 'accesstoken',
success: function (res) {
header.Authorization = res.data;
console.log(header)
console.log(1)
var that=this;
wx.request({
url: apiHost+ url,
method: method,
data: data,
header:header,
success: function (res) {
console.log(res);
if (callback && typeof callback === "function") {
callback(res.data);
}
},
fail: function (error) {
wx.showToast({
title: '网络连接失败',
icon:'none',
duration:2000
})
}
})
},
})
}
注意,wx.request()必须写在wx.getStorage()中的success回调函数中,否则因为异步的原因,会造成header对象未存入token时便已被调用,导致401失败
第二步:暴露函数
在util.js文件最下方进行
module.exports = {
formatTime: formatTime,
Req:Request,
getyear:getyear,
getmonth:getmonth
第三步:获取函数
在全局app.js文件中获取:
var util = require('utils/util.js')
func: { //这里配置我们需要的方法
Req: util.Req,
formatTime:util.formatTime,
getyear:util.getyear,
getmonth:util.getmonth
},
第三步,使用函数:
var app = getApp();
app.func.Req('服务器后缀地址???','GET',function(res){
console.log(res)
console.log(that.myInfor)
})
其中data参数有默认空值,可选填。
注意这里的callback是函数类型的形参,此时函数类型的实参必须用匿名函数,如果调用用了一个定义了的函数名,则会先执行内部的实参函数,此时的res就还未接受到值(为什么?)
全局变量的使用
既然函数都可以全局引用,那么app.js中的全局变量无疑也是可以的。
在app.js文件中存在一个globalData域:
globalData: {
userInfo: null,
newList:[],
all_id:"zcc",
} ,
使用时
在对应的js文件里需要优先声明:
var app = getApp();
然后调用:
app.globalData.all_id = that.data.stu_id
在该项目中,我使用全局变量一个很大的作用是判断用户是否处于登陆状态(因为很多页面的功能都需要判断用户登陆状态以及身份),即给all_id赋给一个初始值,当登陆成功以后会改变这个值,进而可以在每个页面中进行判断。
后来仔细的想了想,其实正是利用了每次开启程序都会重新编译即全局变量又会重新赋初始值的缘故,这让我又因此将其与缓存联想到了一起,仔细理了理他们的区别,缓存记录后如果不是用户清除缓存,便会一直存在,相当于一个小型数据库,可用于用户授权登陆,而全局变量是即使刷新的,适用于用户验证和推广等用途。
首页的轮播图等其实可以存入缓存,这样可以给用户一种即开即显示的感觉,提升用户体验。
我的新闻详情跳转页面也是采用的全局变量:
将新闻存入全局变量中,然后带参数传递一个索引进行定位
带参数传递
gonews:function(e)
{
console.log(e.currentTarget.dataset.id)
var id=e.currentTarget.dataset.id
wx.navigateTo({
url: '../newdetail/newdetail?id='+id,
})
},
<view class="cu-item {{menuArrow?'arrow':''}}" wx:for="{{newList}}" wx-key="{{index}}" data-id="{{index}}" bindtap="gonews">
<view class="content">
<text class="text-black">{{item.title}}</text>
</view>
</view>
将data-id的值接受并传递给即将跳转的页面 id存储在e.currenttargent.dataset.id中
在新闻详情界面:
onLoad: function (options) {
console.log(options)
var ind=options.id;
this.setData({
new_content:app.globalData.newList[ind].paragraphs,
new_title:app.globalData.newList[ind].title
})
},