随着小程序热度飙升,最近公司开发重点转向小程序,目前颜值招聘已发布了2个版本。大概是从3周前开始摸索小程序的,学习过程中,也踩了不少坑。学习新东西获取新技能的那种快感和收获,激励着自己不断学习不断积累不断进步。
关于小程序如何上手以及基本组件、API的介绍,就不赘诉,直接查看官网文档。个人感觉官网链接做的不够好,使用时总会出现搜索跳链混乱问题,推荐使用微信小程序API 文檔快速參考索引。下面就趁着项目迭代的空闲时间,整理并记录下开发中遇到的一些问题,方便自己查阅。
微信提供了一套API供开发者调用,就登录和授权获取用户信息是两个独立的接口,但很多开发人员为了方便经常捆绑在一起使用,登录之后就去获取用户信息,这样的好处是能快速获取到后续请求需要的信息。但有利必有弊,很多时候小程序需要用户登录但并不需要获取用户信息,或者用户授权是滞后或仅在某些场景才需要,这时过早的让用户授权,很可能会使用户产生抵触和反感心理,从而导致部分用户流失。基于项目需求和用户使用习惯考虑,我们决定将登录和授权获取用户信息拆分剥离开。
结合项目需求和安全性考虑,我们设定进小程序的第一条件是登录,只有登录成功才能进入小程序进行后续操作。所有网络请求除登录外,必须在header头里携带定义好的ua字段,ua字段是由设备信息和登录用户的UID、Token等信息拼接成的字符串。
小程序启动时默认调用app.js的 onLaunch() 方法,并读取app.json配置文件,根据pages设置的第一个路径进入对应页面。于是我在app.js的 onLoad() 方法里进行登录并获取设备信息,如下:
onLaunch: function () {
//登录
this.login()
//获取设备信息
this.getDeviceInfo()
}
其中 getDeviceInfo() 方法是自定义的方法,调用微信小程序 wx.getSystemInfo() 并将获取到的信息存在 app.globalData.deviceInfo 中。 login() 方法只是简单调用了服务器的登录接口并保存userInfo
login: function() {
wx.login({
success: function (res) {
if (res.code) {
//请求服务器登录接口
wx.request({
url: loginUrl,
data: {
code: res.code
},
header: {
'content-type': 'application/x-www-form-urlencoded'
},
method: 'POST',
success: function (res) {
if (res.data.ok == 1) {
//存储userInfo
app.globalData.userInfo = res.data.data;
} else {
console.log(res)
wx.showToast({
title: res.data.msg
})
}
}
})
}
},
fail: function () {
wx.showToast({
title: '登录失败'
})
}
})
}
}
video页面是app.json配置文件的第一个路径,也是tabbar的第一个item。进入video页面,会发起请求获取数据,此时就会使用 getApp.globalData.userInfo.uerId 和 getApp.globalData.deviceInfo 组装ua。
onLaunch: function () {
//获取首页数据
this.loadData()
}
项目中对网络请求做了简单的封装放在common.js中,外部调用 common.http(url, method, data, callback, complete)
//网络请求
var http = function (url, method, data, callback, complete) {
var requestUrl = baseUrl + url;
var ua = transformUA();
wx.request({
url: requestUrl,
data,
header: {
'content-type': 'application/x-www-form-urlencoded',
'ua': ua
},
method: method,
success: function (res) {
if (callback != null && callback != 'undefined') {
callback(res);
}
},
complete: function () {
if (complete != null && complete != 'undefined') {
complete();
}
}
})
}
进入video页面时,发现网络请求总是报错未登录。于是我断点排查登录接口,请求是成功的,依旧提示未登录错误信息,和服务端同事沟通,确认是video页面的请求头ua问题导致。断点 transformUA() 方法,发现ua组装时需要的信息是正确的。那时的我就真的懵逼了,参数都对,What happened? 于是和服务端连调,发现登录接口还没完成就在进行video页面的请求,手动捂脸。原来小程序启动和读取配置进页面是同步而非异步的,之前以为调完app.js的onLoad() 方法再根据配置进入页面,理解错了。
那么问题来了,如何保证video页面的网络请求在登录回调成功之后进行呢?
- 方案1:video页面延迟3-5秒再网络请求
- 方案2:登录后置,放video页面,成功再请求首页数据
权衡下,方案1因为网络差异时间不可控,再就是延迟会导致用户体验很差。网络好的情况下,登录回调完成了,进入video页面,此时延迟请求,就会出现几秒的没数据尴尬局面;如果登录还是没完成回调,依然会出现未登录报错的情况。所以方案1不可行。方案2在网络差的情况下和1差不多,而且违背了需求,登录成功才能进入小程序的页面。思考再三,决定强塞页面做个过渡。
具体做法是,新增index页面,app.json配置文件的pages第一个路径设为index文件路径,app.js里的登录逻辑放到index页面,登录成功后再切到第一个tab页面。于是真的出现效果啦,首页数据顺利请求到了,开心~
onLoad: function (options) {
var that = this
wx.login({
success: function (res) {
if (res.code) {
wx.request({
url: loginUrl,
data: {
code: res.code
},
header: {
'content-type': 'application/x-www-form-urlencoded'
},
method: 'POST',
success: function (res) {
if (res.data.ok == 1) {
app.globalData.userInfo = res.data.data;
console.log(app.globalData.userInfo);
//强制页面延迟1s再切换tab
setTimeout(function() {
wx.switchTab({
url: '/pages/video/video'
})
}, 1000);
} else {
console.log(res)
wx.showToast({
title: res.data.msg
})
}
}
})
}
},
fail: function () {
wx.showToast({
title: '登录失败'
})
}
})
}
至此,第一个问题解决了,第一次写工作相关的文章,希望会越来越好,加油~
PS:对于我的问题,各位看官有好的建议或方案,欢迎留言交流,谢谢
网友评论