微信小程式如何確保每個頁面都已經登陸?這篇文章為大家介紹小程式確保每個頁面都登陸的方法,希望對大家有幫助!
一個微信小程式中,有首頁,有個人頁面,還有一些清單頁面,詳情頁面等等,這些頁面大部分是可以分享的。當分享出去的頁面被一個另一個使用者開啟的時候,這個頁面怎麼確保這個使用者已經登陸了呢?
網路上有很多方案是在請求封裝裡面加一道攔截,如果沒有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封裝,你可以依照自己的需求進行新增。總之,我這裡是提供一種思路,如有更佳,歡迎分享。
【相關學習推薦:小程式開發教學】
以上是淺談小程式確保每個頁面都已登陸的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!