一文了解vue中watcher数据双向绑定原理(附代码)
时间:2021-09-03
来源:互联网
标签:
今天PHP爱好者给大家带来vue中watcher数据双向绑定原理分析,之前的文章《解析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
中绑定的回调,则释放自己。
// Watcher
function 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
连起来,先模拟一些数据,实现简单的数据绑定
<p id="name"></p>
<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>
这可以看到p
的和内容初始为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中watcher数据双向绑定原理(附代码)的详细内容,更多请关注php爱好者其它相关文章!
-
如何注册谷歌账号(谷歌账号注册方法) 怎么跳过手机验证 时间:2025-09-29
-
access数据库8个经典实例 时间:2025-09-29
-
mmc.exe是什么进程 mmc.exe应用程序错误的原因及解决方法 时间:2025-09-29
-
4种基本的编程命名规范介绍(匈牙利命名法、驼峰式命名法、帕斯卡命名法、下划线命名法) 时间:2025-09-29
-
Ghostscript下载、安装教程 Ghostscript命令参数详解 时间:2025-09-29
-
Linux中内存管理NUMA架构详解 时间:2025-09-29
今日更新
-
王者荣耀世界英雄怎么获得-王者荣耀世界英雄获取方法
阅读:18
-
饼干人联盟国服怎么样-国服评测详细
阅读:18
-
二重螺旋煜明有什么技能-二重螺旋煜明技能
阅读:18
-
崩坏因缘精灵企茶茶怎么玩-企茶茶设定玩法
阅读:18
-
辉烬手游怎么配队-辉烬阵容搭配方法
阅读:18
-
币安HYPE交易所APP:新兴加密资产投资首选平台
阅读:18
-
四驱兄弟是什么梗?揭秘童年赛车动画爆火网络的新含义!
阅读:18
-
三国天下归心是赛季制吗-赛季机制详细
阅读:18
-
天之炼狱归来魔族厉害吗-魔族强度分析
阅读:18
-
下一站江湖2不水芸丹月怎么获得-获取方法详解
阅读:18