最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

微信小程序如何保證每個頁面都已經(jīng)登陸詳解

 更新時間:2021年11月04日 16:46:17   作者:盜道  
前段時間發(fā)布了一個微信小程序的簡單登錄,但遇到一個問題,怎么確保用戶每個頁面都已經(jīng)登陸了呢,這篇文章主要給大家介紹了關(guān)于微信小程序如何保證每個頁面都已經(jīng)登陸的相關(guān)資料,需要的朋友可以參考下

現(xiàn)狀

一個微信小程序中,有首頁,有個人頁面,還有一些列表頁面,詳情頁面等等,這些頁面大部分是可以分享的。當(dāng)分享出去的頁面被一個另一個用戶打開的時候,這個頁面怎么確保這個用戶已經(jīng)登陸了呢?

網(wǎng)上有很多方案是在請求封裝里面加一道攔截,如果沒有token,就先調(diào)用登陸請求獲取token后,再繼續(xù)。

這種方案沒毛病,只要注意一點,當(dāng)一個頁面有多個請求同時觸發(fā)時,當(dāng)所有請求攔截后,放到一個數(shù)組里面,在獲取token成功后,遍歷數(shù)組一個個請求就行。

但這個需求再復(fù)雜一點,比如連鎖便利店小程序,大部分頁面都需要有一個門店(因為需要根據(jù)門店獲取當(dāng)前門店商品的庫存、價格等),這個門店是根據(jù)當(dāng)前的定位來調(diào)用后臺接口獲得的,這個時候如果在請求里進行封裝就太麻煩了。

解決方案

首先,我們注意到,登陸,獲取定位與我們的頁面請求是異步的,我們需要保證頁面請求是在登陸和獲取定位之后,但要是我們每個頁面都寫一個遍,可維護性就太差了。所以我們可以抽離出一個方法來做這件事。

所以代碼就這樣了:

const app = getApp()
Page({
  data: {
    logs: []
  },
  onLoad() {
    app.commonLogin(()=>{
        // 處理頁頁面請求
    })
  }
})

做到這里好像是解決我們的問題,但再想一想,如果還想做更多的事,比如說每個頁面的onShareAppMessage統(tǒng)一處理,但我又不想在每個頁面再寫一遍,另外,我又想自己對每個頁面實現(xiàn)一個watch,怎么做?

進一步解決方案

我們可以看到微信小程序,每個頁面是一個Page(),那么我們可以給這個Page外面加一層殼子,我們可以有一個MyPage來替換這個Page,廢話不多說,上代碼:

tool.js 相關(guān)代碼

/**
   * 處理合并參數(shù)
   */
  handlePageParamMerge(arg) {
    let numargs = arg.length; // 獲取被傳遞參數(shù)的數(shù)值。
    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
  }

  /***
   * 合并頁面方法以及數(shù)據(jù), 兼容 {data:{}, methods: {}} 或 {data:{}, a:{}, b:{}}
   */
  mergePage() {
    return this.handlePageParamMerge(arguments)
  }

  /**
   * 處理組件參數(shù)合并
   */
  handleCompParamMerge(arg) {
    let numargs = arg.length; // 獲取被傳遞參數(shù)的數(shù)值。
    let data = {}
    let options = {}
    let properties = {}
    let methods = {}
    let comp = {}
    for (let ix in arg) {
      let item = arg[ix]
      // 合并組件的初始數(shù)據(jù)
      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

        //獲取回調(diào)方法
        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)
  }

  /**
    * 設(shè)置監(jiān)聽器
    */
  setWatcher(page) {
    let data = page.data;
    let watch = page.watch;
    Object.keys(watch).forEach(v => {
      let key = v.split('.'); // 將watch中的屬性以'.'切分成數(shù)組
      let nowData = data; // 將data賦值給nowData
      for (let i = 0; i < key.length - 1; i++) { // 遍歷key數(shù)組的元素,除了最后一個!
        nowData = nowData[key[i]]; // 將nowData指向它的key屬性對象
      }

      let lastKey = key[key.length - 1];
      // 假設(shè)key==='my.name',此時nowData===data['my']===data.my,lastKey==='name'
      let watchFun = watch[v].handler || watch[v]; // 兼容帶handler和不帶handler的兩種寫法
      let deep = watch[v].deep; // 若未設(shè)置deep,則為undefine
      this.observe(nowData, lastKey, watchFun, deep, page); // 監(jiān)聽nowData對象的lastKey
    })
  }

  /**
   * 監(jiān)聽屬性 并執(zhí)行監(jiān)聽函數(shù)
   */
  observe(obj, key, watchFun, deep, page) {
    var val = obj[key];
    // 判斷deep是true 且 val不能為空 且 typeof val==='object'(數(shù)組內(nèi)數(shù)值變化也需要深度監(jiān)聽)
    if (deep && val != null && typeof val === 'object') {
      Object.keys(val).forEach(childKey => { // 遍歷val對象下的每一個key
        this.observe(val, childKey, watchFun, deep, page); // 遞歸調(diào)用監(jiān)聽函數(shù)
      })
    }
    var that = this;
    Object.defineProperty(obj, key, {
      configurable: true,
      enumerable: true,
      set: function (value) {
        if (val === value) {
          return
        }
        // 用page對象調(diào)用,改變函數(shù)內(nèi)this指向,以便this.data訪問data內(nèi)的屬性值
        watchFun.call(page, value, val); // value是新值,val是舊值
        val = value;
        if (deep) { // 若是深度監(jiān)聽,重新監(jiān)聽該對象,以便監(jiān)聽其屬性。
          that.observe(obj, key, watchFun, deep, page);
        }
      },
      get: function () {
        return val;
      }
    })
  }

頁面代碼:

app.tool.newPage({
  data: {
    // noAutoLogin: false
  },
  onShow: function () {
    // 在這里寫頁面請求邏輯
  }
}

最后

代碼是在線上跑了很久的,tool里的newPage封裝,你可以根據(jù)自己的需求進行添加??傊疫@里是提供一種思路,如有更佳,歡迎分享。

到此這篇關(guān)于微信小程序如何保證每個頁面都已經(jīng)登陸的文章就介紹到這了,更多相關(guān)微信小程序保證頁面登陸內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • BootStrap下拉框在firefox瀏覽器界面不友好的解決方案

    BootStrap下拉框在firefox瀏覽器界面不友好的解決方案

    BootStrap下拉框在firefox瀏覽器界面很不友好,在firefix瀏覽器打開鏈接就會發(fā)現(xiàn)里面有個小容器,怎么處理呢,下面看下小編給大家分享的有關(guān)這個問題的處理方案
    2016-08-08
  • boostrapTable的refresh和refreshOptions區(qū)別淺析

    boostrapTable的refresh和refreshOptions區(qū)別淺析

    在使用bootstrapTable時,刷新數(shù)據(jù)有兩個方法refresh、refreshOptions,在其用法上有點區(qū)別,接下來通過本文給大家分享boostrapTable的refresh和refreshOptions的區(qū)別,需要的朋友可以參考下
    2017-01-01
  • JS計算網(wǎng)頁停留時間代碼

    JS計算網(wǎng)頁停留時間代碼

    這篇文章主要介紹了JS計算網(wǎng)頁停留時間的具體實現(xiàn),需要的朋友可以參考下
    2014-04-04
  • 前端天氣插件tpwidget使用方法詳解

    前端天氣插件tpwidget使用方法詳解

    這篇文章主要為大家詳細介紹了前端天氣插件tpwidget使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • Javascript中async與await的捕捉錯誤詳解

    Javascript中async與await的捕捉錯誤詳解

    這篇文章主要為大家詳細介紹了Javascript中async與await的捕捉錯誤,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • JS字符串分割方法整理匯總示例講解(3種截取方法和6個輔助方法)

    JS字符串分割方法整理匯總示例講解(3種截取方法和6個輔助方法)

    JavaScript在開發(fā)中常常會需要截取字符串,而JS提供了slice()?、substring()、substr()?3種方法實現(xiàn)截取操作。另外還有字符串相關(guān)的6種輔助方法:indexOf()、lastIndexOf()、split()、join()、concat()、charAt()?。
    2023-02-02
  • 手機端實現(xiàn)Bootstrap簡單圖片輪播效果

    手機端實現(xiàn)Bootstrap簡單圖片輪播效果

    這篇文章主要為大家詳細介紹了基于Bootstrap的簡單輪播圖的手機實現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • JS實現(xiàn)在狀態(tài)欄顯示打字效果完整實例

    JS實現(xiàn)在狀態(tài)欄顯示打字效果完整實例

    這篇文章主要介紹了JS實現(xiàn)在狀態(tài)欄顯示打字效果的方法,涉及JavaScript中字符遍歷結(jié)合時間函數(shù)對狀態(tài)欄顯示進行操作的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-11-11
  • 深入淺析JavaScript中的3DES

    深入淺析JavaScript中的3DES

    本篇文章主要介紹了"javascript中的3des,主要涉及到方面的內(nèi)容,介紹的非常詳細,具有參考借鑒價值,對于js 3des教程感興趣的同學(xué)可以參考一下
    2016-08-08
  • 跨域傳值即主頁面與iframe之間互相傳值

    跨域傳值即主頁面與iframe之間互相傳值

    主頁面A 怎么向 iframe B 傳遞數(shù)據(jù)呢?iframe B 怎么向 主頁面A 傳遞數(shù)據(jù),下面有不錯的實現(xiàn)思路,感興趣的朋友可以了解下
    2013-12-12

最新評論

湖南省| 漳平市| 石景山区| 驻马店市| 北辰区| 乡城县| 龙山县| 林芝县| 文化| 拉孜县| 永和县| 乐业县| 连山| 五莲县| 无为县| 安化县| 湘潭市| 华安县| 钦州市| 龙游县| 邯郸县| 泽普县| 随州市| 鹤壁市| 曲阳县| 陈巴尔虎旗| 临夏县| 大姚县| 安化县| 抚远县| 三亚市| 方山县| 竹北市| 博罗县| 民丰县| 青神县| 芜湖市| 汉源县| 固阳县| 浪卡子县| 重庆市|