浅谈小程序确保每个页面都已登陆的方法

广告:宝塔Linux面板高效运维的服务器管理软件 点击【 https://www.bt.cn/p/uNLv1L 】立即购买

浅谈小程序确保每个页面都已登陆的方法

微信小程序如何确保每个页面都已经登陆?本篇文章给大家介绍一下小程序确保每个页面都登陆的方法,希望对大家有所帮助!

一个微信小程序中,有首页,有个人页面,还有一些列表页面,详情页面等等,这些页面大部分是可以分享的。当分享出去的页面被一个另一个用户打开的时候,这个页面怎么确保这个用户已经登陆了呢?

网上有很多方案是在请求封装里面加一道拦截,如果没有token,就先调用登陆请求获取token后,再继续。这种方案没毛病,只要注意一点,当一个页面有多个请求同时触发时,当所有请求拦截后,放到一个数组里面,在获取token成功后,遍历数组一个个请求就行。

但这个需求再复杂一点,比如连锁便利店小程序,大部分页面都需要有一个门店(因为需要根据门店获取当前门店商品的库存、价格等),这个门店是根据当前的定位来调用后台接口获得的,这个时候如果在请求里进行封装就太麻烦了。

解决方案

首先,我们注意到,登陆,获取定位与我们的页面请求是异步的,我们需要保证页面请求是在登陆和获取定位之后,但要是我们每个页面都写一个遍,可维护性就太差了。所以我们可以抽离出一个方法来做这件事。所以代码就这样了:

const app = getApp()Page({  data: {    logs: []  },  onLoad() {    app.commonLogin(()=>{        // 处理页页面请求    })  }})
登录后复制

做到这里好像是解决我们的问题,但再想一想,如果还想做更多的事,比如说每个页面的onShareAppMessage统一处理,但我又不想在每个页面再写一遍,另外,我又想自己对每个页面实现一个watch,怎么做?

进一步解决方案

我们可以看到微信小程序,每个页面是一个Page(),那么我们可以给这个Page外面加一层壳子,我们可以有一个MyPage来替换这个Page,废话不多说,上代码:

tool.js 相关代码

/**   * 处理合并参数   */  handlePageParamMerge(arg) {    let numargs = arg.length; // 获取被传递参数的数值。    let data = {}    let page = {}    for (let ix in arg) {      let item = arg[ix]      if (item.data && typeof (item.data) === 'object') {        data = Object.assign(data, item.data)      }      if (item.methods && typeof (item.methods) === 'object') {        page = Object.assign(page, item.methods)      } else {        page = Object.assign(page, item)      }    }    page.data = data    return page  }  /***   * 合并页面方法以及数据, 兼容 {data:{}, methods: {}} 或 {data:{}, a:{}, b:{}}   */  mergePage() {    return this.handlePageParamMerge(arguments)  }  /**   * 处理组件参数合并   */  handleCompParamMerge(arg) {    let numargs = arg.length; // 获取被传递参数的数值。    let data = {}    let options = {}    let properties = {}    let methods = {}    let comp = {}    for (let ix in arg) {      let item = arg[ix]      // 合并组件的初始数据      if (item.data && typeof (item.data) === 'object') {        data = Object.assign(data, item.data)      }      // 合并组件的属性列表      if (item.properties && typeof (item.properties) === 'object') {        properties = Object.assign(properties, item.properties)      }      // 合组件的方法列表      if (item.methods && typeof (item.methods) === 'object') {        methods = Object.assign(methods, item.methods)      }      if (item.options && typeof (item.options) === 'object') {        options = Object.assign(options, item.options)      }      comp = Object.assign(comp, item)    }    comp.data = data    comp.options = options    comp.properties = properties    comp.methods = methods    return comp  }  /**   * 组件混合 {properties: {}, options: {}, data:{}, methods: {}}   */  mergeComponent() {    return this.handleCompParamMerge(arguments)  }  /***   * 合成带watch的页面   */  newPage() {    let options = this.handlePageParamMerge(arguments)    let that = this    let app = getApp()    //增加全局点击登录判断    if (!options.publicCheckLogin){      options.publicCheckLogin = function (e) {        let pages = getCurrentPages()        let page = pages[pages.length - 1]        let dataset = e.currentTarget.dataset        let callback = null        //获取回调方法        if (dataset.callback && typeof (page[dataset.callback]) === "function"){          callback = page[dataset.callback]        }        // console.log('callback>>', callback, app.isRegister())        //判断是否登录        if (callback && app.isRegister()){          callback(e)        }        else{          wx.navigateTo({            url: '/pages/login/login'          })        }      }    }    const { onLoad } = options    options.onLoad = function (arg) {      options.watch && that.setWatcher(this)      onLoad && onLoad.call(this, arg)    }    const { onShow } = options    options.onShow = function (arg) {      if (options.data.noAutoLogin || app.isRegister()) {        onShow && onShow.call(this, arg)        //页面埋点        app.ga({})      }      else {        wx.navigateTo({          url: '/pages/login/login'        })      }    }    return Page(options)  }  /**   * 合成带watch等的组件   */  newComponent() {    let options = this.handleCompParamMerge(arguments)    let that = this    const { ready } = options    options.ready = function (arg) {      options.watch && that.setWatcher(this)      ready && ready.call(this, arg)    }    return Component(options)  }  /**    * 设置监听器    */  setWatcher(page) {    let data = page.data;    let watch = page.watch;    Object.keys(watch).forEach(v => {      let key = v.split('.'); // 将watch中的属性以'.'切分成数组      let nowData = data; // 将data赋值给nowData      for (let i = 0; i < key.length - 1; i++) { // 遍历key数组的元素,除了最后一个!        nowData = nowData[key[i]]; // 将nowData指向它的key属性对象      }      let lastKey = key[key.length - 1];      // 假设key==='my.name',此时nowData===data['my']===data.my,lastKey==='name'      let watchFun = watch[v].handler || watch[v]; // 兼容带handler和不带handler的两种写法      let deep = watch[v].deep; // 若未设置deep,则为undefine      this.observe(nowData, lastKey, watchFun, deep, page); // 监听nowData对象的lastKey    })  }  /**   * 监听属性 并执行监听函数   */  observe(obj, key, watchFun, deep, page) {    var val = obj[key];    // 判断deep是true 且 val不能为空 且 typeof val==='object'(数组内数值变化也需要深度监听)    if (deep && val != null && typeof val === 'object') {      Object.keys(val).forEach(childKey => { // 遍历val对象下的每一个key        this.observe(val, childKey, watchFun, deep, page); // 递归调用监听函数      })    }    var that = this;    Object.defineProperty(obj, key, {      configurable: true,      enumerable: true,      set: function (value) {        if (val === value) {          return        }        // 用page对象调用,改变函数内this指向,以便this.data访问data内的属性值        watchFun.call(page, value, val); // value是新值,val是旧值        val = value;        if (deep) { // 若是深度监听,重新监听该对象,以便监听其属性。          that.observe(obj, key, watchFun, deep, page);        }      },      get: function () {        return val;      }    })  }
登录后复制

页面代码:

app.tool.newPage({  data: {    // noAutoLogin: false  },  onShow: function () {    // 在这里写页面请求逻辑  }}
登录后复制

最后

代码是在线上跑了很久的,tool里的newPage封装,你可以根据自己的需求进行添加。总之,我这里是提供一种思路,如有更佳,欢迎分享。

【相关学习推荐:小程序开发教程】

以上就是浅谈小程序确保每个页面都已登陆的方法的详细内容,更多请关注9543建站博客其它相关文章!

广告:SSL证书一年128.66元起,点击购买~~~

9543建站博客
一个专注于网站开发、微信开发的技术类纯净博客。
作者头像
admin创始人

肥猫,知名SEO博客站长,14年SEO经验。

上一篇:yii框架实现图片上传源码分享
下一篇:有关百度指数的文章推荐4篇

发表评论

关闭广告
关闭广告