前几天准备回去架构组来着,但是那边新来了个妹子在搞,新项目有还没启动,小程序一直有项目,又没人,一直在小程序的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
,那么系统会报一个超出最大堆栈大小,RangeError: Maximum call stack size exceeded at Object.set [as isLogin]
,首先可以确定的是进入死循环了,其实就是在set的时候调用了get,this.isLogin = value
,无限循环了,解决方式为只需要找一个值替代即可,使用替代值或者屏蔽掉都可以. -
关于this, 在watchBack函数中直接使用
this.methods...
这样调用方法是行不通的,watchBack是拿不到this的,会报一个undefined,因为它是回调函数中的this,解决方法:app.watchLogin()
传个this即可
欢迎交流,转载注明出处即可