微信小程序开发

强塞过渡页面

2018-01-30  本文已影响35人  舒小妮儿

随着小程序热度飙升,最近公司开发重点转向小程序,目前颜值招聘已发布了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.uerIdgetApp.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:对于我的问题,各位看官有好的建议或方案,欢迎留言交流,谢谢

上一篇下一篇

猜你喜欢

热点阅读