您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

一文了解vue中watcher数据双向绑定原理(附代码)

2024/3/1 6:14:52发布51次查看
之前的文章《解析vue中observer数据双向绑定原理(代码分享)》中,给大家了解了vue中observer数据双向绑定原理。下面本篇文章给大家了解vue中watcher数据双向绑定原理,一定的参考价值,有需要的朋友可以参考一下。
vue数据双向绑定原理,和简单的实现,本文将实现mvvm的watcher
1)vue数据双向绑定原理-observer
2)vue数据双向绑定原理-wather
3)vue数据双向绑定原理-解析器complie
vue数据双向绑定原理,和简单的实现,本文将实现mvvm的watcher
上面的步骤已经实现了监听器,和订阅器,当属性发生改变,发出通知,那么这个通知是通知谁呢,肯定是订阅者watcher.watcher订阅者作为observer和compile之间通信的桥梁,主要做的事情是:
1、在自身实例化时往属性订阅器(dep)里面添加自己
2、自身必须有一个update()方法
3、待属性变动dep.notice()通知时,能调用自身的update()方法,并触发compile中绑定的回调,则释放自己。
// watcherfunction watcher(vm, exp, cb) { this.cb = cb; this.$vm = vm; this.exp = exp; // 此处为了触发属性的getter,从而在dep添加自己,结合observer更易理解 this.value = this.get(); // 将自己添加到订阅器的操作}watcher.prototype = { update: function () { this.run(); // 属性值变化收到通知 }, run: function () { var value = this.get(); // 取到最新值 var oldval = this.value; if (value !== oldval) { this.value = value; this.cb.call(this.$vm, value, oldval); // 执行compile中绑定的回调,更新视图 } }, get: function () { dep.target = this; // 将当前订阅者指向自己, 缓存 var value = this.$vm[this.exp]; // 强制触发监听的getter,添加自己到属性订阅器中 dep.target = null; // 添加完毕,重置释放 return value; },};
订阅者要缓存自己,并且告诉监听器,要把我加到订阅器里面去。所以还要改造下监听器
function definereactive(data, key, val) { var dep = new dep() observe(val); // 监听子属性 object.defineproperty(data, key, { .... get: function() { // 由于需要在闭包内添加watcher,所以可以在dep定义一个全局target属性,暂存watcher, 添加完移除 dep.target && dep.adddep(dep.target); return val; }, .... });}
实例化watcher的时候,调用get()方法,通过dep.target=watcherinstance标记订阅者是当前watcher实例,强行触发属性定义的getter方法,getter方法执行的时候,就会在属性的订阅器dep添加当前watcher实例,从而在属性值有变化的时候watcherinstance就能收到更新通知。
实现mvvm到这儿先将监听器observer和监听者watcher连起来,先模拟一些数据,实现简单的数据绑定
<div id="name"></div><script> function vue(data, el, exp) { this.data = data; observe(data); el.innerhtml = this.data[exp]; // 初始化模板数据的值 new watcher(this, exp, function (value) { el.innerhtml = value; }); return this; } var ele = document.queryselector("#name"); var vue = new vue( { name: "hello world", }, ele, "name" ); setinterval(function () { vue.data.name = "chuchur " + new date() * 1; }, 1000);</script>
这可以看到div的和内容初始为hello world,每隔一秒之后变换为chuchur加时间戳,虽然是实现了,但是与想象的还差很多。是vue.name不是vue.data.name,所以这里需要给vue实例添加一个属性代理的方法,使访问vm的属性代理为访问vm.data的属性,改造后的代码如下:
function vue(options) { this.$options = options || {}; this.data = this.$options.data; // 属性代理,实现 vm.xxx -> vm.data.xxx var self = this; object.keys(this.data).foreach(function(key) { self.proxy(key); // 绑定代理属性 }); observe(this.data, this); el.innerhtml = this.data[exp]; // 初始化模板数据的值 new watcher(this, exp, function(value) { el.innerhtml = value; }); return this;}vue.prototype = { proxy: function(key) { var self = this; object.defineproperty(this, key, { enumerable: false, configurable: true, get: function proxygetter() { return self.data[key]; }, set: function proxysetter(newval) { self.data[key] = newval; } }); }}
然后就可以通过vue.name,直接改版模板的数据了,下一步就要实现解析器complie 
[完]
推荐学习:vue.js教程
以上就是一文了解vue中watcher数据双向绑定原理(附代码)的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product