uniapp 将globalData变为响应式 proxy 数据劫持

结合defineProperties,proxy将globalData变为响应式

自己写了一个简单的响应式方法,可以监听globalData对象的变化并获取新的值。每一层都可以单独监听,最小监听层级为Object(即{}),基础数据类型目前无法监听。

1、将文件拷贝到目录并引入app.vue

// 文件内容 ./proxyUtil.js
let that = null

function ProxyPlus(obj) {
	if (typeof obj === 'object') {
		// 如果对象已经被处理过了 跳过
		if (obj.hasOwnProperty('_subs')) {
			return obj
		}
		// 定义 订阅者队列、观察回调函数(用于发布时调用)、值改变发布函数、销毁订阅者函数
		Object.defineProperties(obj, {
			// 订阅者队列
			_subs: {
				enumerable: false,
				configurable: false,
				value: []
			},
			// 观察回调 返回销毁方法,页面关闭时可调用销毁订阅者
			watch: {
				enumerable: false,
				configurable: false,
				value: function(fn) {
					obj._subs.push(fn)
					fn(obj)
					return {
						destory: function() {
							obj._subs.splice(obj._subs.indexOf(fn), 1)
						}
					}
				}
			},
			// 发布函数
			notify: {
				enumerable: false,
				configurable: false,
				value: function() {
					obj._subs.forEach(fn => fn(obj))
				}
			},

		})
		// obj数据劫持,get和set时执行相应操作
		obj = new Proxy(obj, {
			get: function(target, key) {
				// console.log(`get:${key}`)
				return target[key]
			},
			set: function(target, key, value) {
				if (target[key] === value) {
					return true
				}
				target[key] = ProxyPlus(value)
				// console.log(`set:${key},notify`)
				target.notify()
				return true
			}
		})

		// 递归遍历obj,确保每一层都被处理为响应式
		for (const key in obj) {
			obj[key] = ProxyPlus(obj[key])
		}
	}
	return obj
}


module.exports = (_this) => {
	that = _this
	that.globalData = ProxyPlus(that.globalData)
	// console.log(that.globalData)
}

// 引入语句 ./vue.js script标签中
const proxyUtil = require('./proxyUtil')

2、app.vue 初始化时将this传入函数 处理globalData

		globalData: {
			userInfo: {
				
			},
		},
		onLaunch: function() {
			console.log('App Launch')
			proxyUtil(this)	// 传入this,将处理globalData对象并将处理后的对象替换现有对象
		},

3、在其他页面使用

// ./pages/menu.vue
		data() {
			return {
				userInfo: {}
			}
		},
// 页面显示时获取:调用对象的watch函数(最小监听层级为Object,目前基础数据类型无法监听),传入回调函数,参数为全局对象更新后的值。
// 这里的返回值为监听对象,要储存起来,之后可以调用destory()函数将监听对象销毁
		onShow() {
			this.gloBalUserInfoWatcher = getApp().globalData.userInfo.watch(gloBalUserInfo =>{
				this.userInfo = gloBalUserInfo
			})
		},

// 最后在页面关闭时销毁监听对象
		onUnload() {
			console.log('close')
			this.gloBalUserInfoWatcher.destory()
		}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值