强塞过渡页面

作者: 舒小妮儿 | 来源:发表于2018-01-30 18:37 被阅读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:对于我的问题,各位看官有好的建议或方案,欢迎留言交流,谢谢

    相关文章

      网友评论

        本文标题:强塞过渡页面

        本文链接:https://www.haomeiwen.com/subject/lhrczxtx.html