您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“小程序如何確保每個頁面都已登陸”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“小程序如何確保每個頁面都已登陸”這篇文章吧。
一個微信小程序中,有首頁,有個人頁面,還有一些列表頁面,詳情頁面等等,這些頁面大部分是可以分享的。當分享出去的頁面被一個另一個用戶打開的時候,這個頁面怎么確保這個用戶已經登陸了呢?
網上有很多方案是在請求封裝里面加一道攔截,如果沒有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 () { // 在這里寫頁面請求邏輯 } }
以上是“小程序如何確保每個頁面都已登陸”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。