浅析Proxy可以优化vue的数据监听机制问题及实现思
网络编程 2021-07-04 16:47www.168986.cn编程入门
这篇文章主要介绍了浅析Proxy可以优化vue的数据监听机制问题及实现思路,需要的朋友可以参考下
我们来看vue2.x中的实现,为简单起见,我们这里不考虑多级嵌套,也不考虑数组
vue2.x中的实现
其本质是new Watcher(data, key, callback)
的方式,而在调用之前是先将data中的所有属性转化成可监听的对象, 其主要就是利用Object.defineProperty
,。
class Watcher{ constructor(data, key, cb){ } } //转换成可监听对象 function observe(data){ new Observer(data) } //修改数据的getter和setter function defineReactive(obj, key){ let value = obj[key]; Object.defineProperty(obj, key, { enumerable: true, configurable: true, get(){ return value; }, set(newVal){ value = newVal } }) }
Observer的实现很简单
class Observer { constructor(data){ this.walk(data); } walk(data){ for(var key in data) { // 这里不考虑嵌套的问题,否则的话需要递归调用walk defineReactive(data, key) } } }
现在怎么将watcher和getter/setter联系起来,vue的方法是添加一个依赖类Dep
class Watcher{ constructor(data, key, cb){ this.cb = cb; Dep.target = this; //每次新建watcher的时候讲给target赋值,对target的管理这里简化了vue的实现 data[key];//调用getter,执行addSub, 将target传入对应的dep; vue的实现本质就是如此 } } class Dep { constructor(){ this.subs = []; } addSub(sub){ this.subs.push(sub); } notify(){ this.subs.forEach(sub => sub.cb()) } } function defineReactive(obj, key){ let value = obj[key]; let dep = new Dep(); //每一个属性都有一个对应的dep,作为闭包保存 Object.defineProperty(obj, key, { enumerable: true, configurable: true, get(){ dep.addSub(Dep.target) Dep.target = null; return value; }, set(newVal){ value = newVal dep.notify(); } }) }
以上就是vue的思路,vue3之所以要从新实现,主要有这几个原因
- Object.defineProperty的性能开销。
- defineReactive一开始就要对要监听的对象所有属性都执行一遍,因为传统方法要将一个对象转换成可监听对象,只能如此。
- 添加删除属性的问题。
- 还有一点就是这个模块被耦合到了vue里面,新版本可以单独作为一个库来使用。
然后我们来看看同样的功能采用Proxy会怎样实现。
Proxy的实现
将一个对象转换成Proxy的方式很简单,只需要作为参数传给proxy即可;
class Watcher { constructor(proxy, key, cb) { this.cb = cb; Dep.target = this; this.value = proxy[key]; } } class Dep { constructor(){ this.subs = [] } addSub(sub){ this.subs.push(sub); } notify(newVal){ this.subs.forEach(sub => { sub.cb(newVal, sub.value); sub.value = newVal; }) } } const observe = (obj) => { const deps = {}; return new Proxy(obj, { get: function (target, key, receiver) { const dep = (deps[key] = deps[key] || new Dep); Dep.target && dep.addSub(Dep.target) Dep.target = null; return Reflect.get(target, key, receiver); }, set: function (target, key, value, receiver) { const dep = (deps[key] = deps[key] || new Dep); Promise.resolve().then(() => { dep.notify(value); }) return Reflect.set(target, key, value, receiver); } }); } var state = observe({x:0}) new Watcher(state, 'x', function(n, o){ console.log(n, o) }); new Watcher(state, 'y', function(n, o){ console.log(n, o) }); state.x = 3; state.y = 3;
也许一开始我们只关心x和y,那么就不会对其他的属性做相应的处理,除非添加watcher,其他时间target都是null
以上所述是长沙网络推广给大家介绍的Proxy可以优化vue的数据监听机制问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,长沙网络推广会及时回复大家的。在此也非常感谢大家对狼蚁SEO网站的支持!
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程