vue2.0响应式原理,vue 响应式
本文主要介绍Vue2响应系统,主要实现一个依赖于数据的功能。当相关数据发生变化时,必须重新执行该功能。有关下面的更多信息,请参考所需的合作伙伴。
:
目录
1.响应系统应该做什么。响应数据3。保存当前执行的功能4。响应数据5。观察者对象6。测试7。总结前言:。
目前,工作中可能有一些需求正在使用技术堆栈。知道是什么就知道为什么更重要。为了更好地使用它,更快地解决问题,我最近学习了一些与源代码相关的知识。虽然网上的总结很多,很多都有自己的,但是自己的不多。欢迎大家一起讨论学习,发现问题请指出。40%Vue2VueVue
一、响应式系统要干什么
回到最简单的代码:
数据={
文本:“你好,世界”
}
const updateComponent=()={
Console.log (received ,data . text);
}
更新组件()
data.text=你好,梁
//运行结果
//收到hello,world
一个响应系统需要做什么:一个依赖于数据的功能。当相关数据发生变化时,需要重新执行该函数。数据数据
我们期望的效果:修改上述内容后,再次执行该功能。data.textupdateComponent
为了实现响应式系统,我们需要做两件事情:
当您知道哪些函数依赖于datadata中的数据时,调用依赖于它的函数。为了实现点,我们需要在执行函数时保存当前函数,然后将函数保存到读取数据处的当前数据。一个
第一点解决了。当修改数据时,保存的功能可以执行一次。2
在读取数据和修改数据中,我们需要做一些额外的事情。我们可以重写对象属性的sum函数。Object.defineProperty()getset
二、响应式数据
让我们编写一个覆盖属性求和函数的函数。装置
/**
*定义对象的反应属性。
*/
导出函数defineReactive(obj,key,val) {
const property=object . getownpropertydescriptor(obj,key);
//读取用户可能自己定义的get,set。
const getter=property property . get;
const setter=property property . set;
//val没有用于手动分配的来电
如果((!getter setter)arguments . length===2){
val=obj[key];
}
Object.defineProperty(obj,key,{
可枚举:真,
可配置:真,
get:函数reactiveGetter() {
const value=getter?getter . call(obj):val;
/*********************************************/
//1.这里你需要保存当前正在执行的函数。
/*********************************************/
返回值;
},
set:函数reactiveSetter(newVal) {
const value=getter?getter . call(obj):val;
if (setter) {
setter.call(obj,new val);
}否则{
val=newVal
}
/*********************************************/
//2.将执行依赖于当前数据相关性的函数。
/*********************************************/
},
});
}
为了调用方便,我们将step和step中的操作封装成一个类。12Dep
导出默认类Dep {
静态目标;//当前正在执行的函数
潜艇;//依赖函数
构造函数(){
this . subs=[];//保存所有需要执行的功能
}
addSub(sub) {
this . subs . push(sub);
}
依赖(){
//触发get时转到此处
if (Dep.target) {
//委托Dep.target调用addSub
dep . target . add dep(this);
}
}
通知(){
for(设i=0,l=this . subs . length;I l;i ) {
this.subs[i]。update();
}
}
}
Dep.target=null//静态变量,全局唯一
我们将当前执行的函数保存到类的变量中。Deptarget
三、保存当前正在执行的函数
为了保存当前函数,我们还需要写一个类,传入要执行的函数,保存在类的属性中,然后交给类执行。WatcherWatchergetterWatcher
这样,在类中,不是保存当前函数,而是保存当前函数的对象。DepsubsWatcher
从导入Dep。/dep ;
导出默认类观察器{
构造函数(Fn) {
this.getter=Fn
this . get();
}
/**
*评估getter,并重新收集依赖项。
*/
get() {
Dep.target=this//保存包装当前正在执行的函数的观察器。
让价值;
尝试{
//调用当前传入函数触发对象属性的get
value=this . getter . call();
} catch (e) {
扔e;
}
返回值;
}
/**
*向此指令添加依赖项。
*/
addDep(dep) {
//在触发get之后,您将转到这里并收集当前的依赖项
//当前正在执行的函数的监视器被保存到dep中的subs中
dep . addsub(this);
}
/**
*用户界面。
*当依赖关系改变时将被调用。
*/
//修改对象属性值时触发set。去这里。
update() {
this . run();
}
/**
*调度程序作业界面。
*将由调度程序调用。
*/
run() {
this . get();
}
}
Watcher的作用是把正在执行的函数包装起来保存进去,然后调用传入的函数。此时,触发object属性的函数将收集当前的。WatcherDep.targetgetWatcher
如果将来修改了object属性的值,就会触发object属性,然后调用之前收集的对象,通过object的方法调用最初执行的函数。setWatcherWatcheruptate
四、响应式数据
让我们回到之前没有完成的函数。按照上面的思路,我们来完成吧。定义活动
从导入Dep。/dep ;
/**
*定义对象的反应属性。
*/
导出函数defineReactive(obj,key,val) {
const property=object . getownpropertydescriptor(obj,key);
//读取用户可能自己定义的get,set。
const getter=property property . get;
const setter=property property . set;
//val没有用于手动分配的来电
如果((!getter setter)arguments . length===2){
val=obj[key];
}
/*********************************************/
const Dep=new Dep();//保存一个Dep对象来保存依赖于该变量所有观察器
/*********************************************/
Object.defineProperty(obj,key,{
可枚举:真,
可配置:真,
get:函数reactiveGetter() {
const value=getter?getter . call(obj):val;
/*********************************************/
//1.这里你需要保存当前正在执行的函数。
if (Dep.target) {
dep . depend();
}
/*********************************************/
返回值;
},
set:函数reactiveSetter(newVal) {
const value=getter?getter . call(obj):val;
if (setter) {
setter.call(obj,new val);
}否则{
val=newVal
}
/*********************************************/
//2.将执行依赖于当前数据相关性的函数。
dep . notify();
/*********************************************/
},
});
}
五、Observer 对象
让我们再写一个方法,让对象的所有属性都有响应。观察者
导出类观察者{
构造函数(值){
this.walk(值);
}
/**
*遍历对象的所有属性,并调用defineReactive。
*拦截对象属性的get和set方法。
*/
步行
const keys=object . keys(obj);
for(设I=0;i keys.lengthi ) {
defineReactive(obj,keys[I]);
}
}
}
我们提供了一个负责创建对象的方法。观察者
导出函数观察(值){
设ob=新观察者(值);
返回ob;
}
六、测试
将上边的方法引入到文章最开头的例子,来执行一下:
从导入{ observe }。/reactive ;
从导入观察器。/watcher ;
常量数据={
文字:“你好,世界”,
};
//使数据具有响应性
观察(数据);
const updateComponent=()={
Console.log (received ,data . text);
};
//当前函数由Watcher执行
新观察器(update component);
data.text=你好,梁;
这时候就会输出两次~
收到,你好,世界
收到,喂,梁
这表明我们的响应系统是成功的。
七、总结
先从整体理解了响应式系统的整个流程:
每个属性都有一个数组,用来保存当前执行的函数。当属性被读取时,它将被触发,当前值将被保存在数组中。当属性值被修改时,先前保存的函数将通过数组中的对象执行。subwatchergetwatchers sub watcher
关于Vue2响应式系统介绍的这篇文章到此为止。有关Vue2响应式系统的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望大家以后能多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。