前幾天準備回去架構組來着,但是那邊新來了個妹子在搞,新項目有還沒啟動,小程式一直有項目,又沒人,一直在小程式的feature-team中,這不又來個幾個需求。
其中一個新需求是需要做一個協定更新的功能,即老使用者登入後,接口檢查一遍協定是否已更新,需要重新同意協定,否則直接退出小程式。
查了一下沒有全局元件的說法,問了隔壁老王,老徐有什麼比較好的方法,都丢下一句話,寫個component然後挨個頁面引入,在每個頁面做一遍标簽引入,然後傳值給子元件,子元件observe即可。
按照正常實作我感覺這個改動還挺大的,首先每個頁面都得引入标簽指派狀态。而我的想法是全部功能在元件内實作,頁面隻需要用一個标簽即可,元件内監聽登入态即可,想了一下試試資料劫持的實作模式:
app.js
// 使用資料劫持模式去監聽登入狀态
watchLogin(callback, that){
console.log("this.globalData", this.globalData)
var obj = this.globalData;
Object.defineProperty(obj,"isLogon", {
configurable: true,
enumerable: true,
set: function (value) {
this._isLogon = value;
console.log('登入狀态被指派',this._isLogon)
callback(value, that);
},
get:function(){
return this._isLogon
}
})
},
元件内:
const app = getApp() //擷取應用執行個體
methods: {
//登入狀态回調
watchBack(isLogon, that){
console.log('登入狀态資料變化 isLogon', isLogon)
console.log("watchBack this",this) // 這裡的this是無效的
console.log("watchBack that",that.data)
if (isLogon) {
...that.methodsName()
}
},
}
/*元件生命周期*/
lifetimes: {
created() {
},
attached() {
console.log("在元件執行個體進入頁面節點樹時執行")
// 調用app中監聽登入狀态的方法
app.watchLogin(this.watchBack, this)
}
}
基本就實作了一個全局狀态的監聽更新,登入狀态改變時會自動觸發setter,然後觸發callback,将setter的value以參數的方式傳過來判斷一下就可以使用了。
注意:開發過程還需要注意兩個問題
- Object.defineProperty資料劫持時,如果在setter中直接寫
,那麼系統會報一個超出最大堆棧大小,this.isLogon = value
,首先可以确定的是進入死循環了,其實就是在set的時候調用了get,RangeError: Maximum call stack size exceeded at Object.set [as isLogin]
,無限循環了,解決方式為隻需要找一個值替代即可,使用替代值或者屏蔽掉都可以.this.isLogin = value
- 關于this, 在watchBack函數中直接使用
這樣調用方法是行不通的,watchBack是拿不到this的,會報一個undefined,因為它是回調函數中的this,解決方法:this.methods...
傳個this即可app.watchLogin()
歡迎交流,轉載注明出處即可