“This is the second day of my participation in the Gwen Challenge in November. See details: The Last Gwen Challenge in 2021”

The status quo

In a micro channel small program, there is a home page, a personal page, and some list pages, details pages and so on, most of these pages can be shared. When a shared page is opened by another user, how does the page ensure that the user has logged in?

There are many schemes on the Internet that add an interception in the request encapsulation. If there is no token, the login request will be called first to obtain the token, and then continue. There is nothing wrong with this solution, as long as you note that when multiple requests are triggered on a page, all the requests are intercepted, put into an array, and after the token is successfully obtained, iterate through the list of requests one by one.

Again a little bit complicated, but this demand chain convenience store small program, for example, most of the page needs to have a store (because the need according to get the current the goods store inventory, price, etc.), this store is based on the current location to invoke the backend interface, encapsulate in this time if the request is too much trouble.

The solution

First of all, we noticed that the login and fetch location are asynchronous with our page requests. We need to make sure that the page request is after the login and fetch location, but if we write every page once, the maintainability would be poor. So we can isolate a way to do this. So here’s the code:

Const app = getApp() Page({data: {logs: []}, onLoad() {app.commonLogin(()=>{// handle Page Page request})}})Copy the code

This seems to solve our problem, but think again, if I want to do more things, such as unified processing of onShareAppMessage for each page, but I don’t want to write it again for each page, and I want to implement a watch for each page, what should I do?

Further solutions

Each Page is a Page(), so we can add a shell to the Page, we can have a MyPage to replace the Page, without further talk, on the code:

Tool.js related code

/** * handlePageParamMerge(arg) {let numargs = arg.length; // Get the value of the passed argument. 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} /*** * merge page methods and data, Compatible with {data: {}, the methods: {}} or {data: {}, a: {}, B: {}} * / mergePage () {return enclosing handlePageParamMerge (the arguments)} / processing component parameter * * * * / handleCompParamMerge (arg) {let numargs = arg.length; // Get the value of the passed argument. let data = {} let options = {} let properties = {} let methods = {} let comp = {} for (let ix in arg) { let item = If (item.data && typeof (item.data) === 'object') {data = object.assign (data, If (item.properties && typeof (item.properties) === 'object') {properties = Object.assign(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 } /** * Component Blending {properties: {}, options: {}, data:{}, methods: {{}} * / mergeComponent () return this. HandleCompParamMerge (the arguments)} / * * * * * synthesis with watch page/brought () {let options = Enclosing handlePageParamMerge (the arguments) let that = this let app = getApp () / / increase global click login to judge the if (! options.publicCheckLogin){ options.publicCheckLogin = function (e) { let pages = getCurrentPages() let page = Pages [pages.length-1] let dataset = e.currenttarget. Dataset let callback = null // Retrieve callback method if (dataset.callback && typeof (page[dataset.callback]) === "function"){ callback = page[dataset.callback] } // console.log('callback>>', 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()) { App.ga ({})} else {wx.navigateTo({url: '/pages/login/login'})}} return Page(options)} /** * 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)} /** * set listener */ setWatcher(page) {let data = page.data; let watch = page.watch; Object.keys(watch).forEach(v => { let key = v.split('.'); // Let nowData = data; // Assign data to nowData for (let I = 0; i < key.length - 1; I++) {// iterate over the elements of the key array, except for the last one! nowData = nowData[key[i]]; } let lastKey = key[key.length-1]; / / assume that key = = = '. My name ', the nowData = = = data [' my '] = = = data. My lastKey = = = 'name' let watchFun = watch [v]. Handler | | watch [v]; // Let deep = watch[v].deep; // Undefine this.observe(nowData, lastKey, watchFun, deep, page); Observe (obj, key, watchFun, deep, page) {var val = obj[key]; Typeof val==='object' if (deep && val! = null && typeof val === 'object') {object.keys (val).foreach (childKey => {childKey => {childKey => {childKey => this. childKey, watchFun, deep, page); })} var that = this; Object.defineProperty(obj, key, { configurable: true, enumerable: true, set: Watchfun. call(function (value) {if (val === value) {return} function (value) {if (val === value) {return} value, val); // value = new value, val = old value; If (deep) {// If deep listening, re-listen the object to listen for its properties. that.observe(obj, key, watchFun, deep, page); } }, get: function () { return val; }})}Copy the code

Page code:

App.tool. newPage({data: {// noAutoLogin: false}, onShow: function () {// write page request logic here}}Copy the code

The last

The code is a newPage wrapper in tool that has been running online for a long time, and you can add it as needed. In short, I am here to provide a way of thinking, if there is better, welcome to share.