obrve

更新时间:2022-11-23 08:19:24 阅读: 评论:0


2022年11月23日发(作者:代词有哪些)

【⼿把⼿教你搓Vue响应式原理】(三)obrve以及__ob__

⼤家好,我是辉夜真是太可爱啦。这是我最近在写的【⼿把⼿教你搓Vue响应式原理】系列,本⽂将⼀步步地为你解开

vue响应式原理的⾯纱。由于本⼈也是在写这篇⽂章的过程中不断试错,不断学习改进的,所以,本⽂同样很适合和我⼀

样的初学者。和Vue的设计理念如出⼀辙,那就是渐进增强。

上⽂链接

【⼿把⼿教你搓Vue响应式原理】(⼀)初识Vue响应式

【⼿把⼿教你搓Vue响应式原理】(⼆)深度监测对象全部属性

前⾔

在上⼀⽂中,我们已经成功将深度对象(好⼏层的对象)成功遍历,全部绑定了

defineReactive

,也就是全部弄成了响应式对象。

虽然上述功能已经基本实现了对象的成功遍历,但是,在Vue的源码中,在我们遍历对象的同时,会将

newObrver()

创建的实例赋值到

__ob__

属性添加到每⼀个对象中。

这篇⽂章主要对标源码,新增了

__ob__

属性,以及

obrve

⼊⼝⽅法,相当于是对标源码,更规范地书写响应式。

这个

__ob__

属性,在vue使⽤中⼤家也可能有所眼熟,这篇⽂章本意也在于更规范地书写响应式。

并且,由于少了⼀个

obrve

⼊⼝⽅法,也是为了上⼀⽂中关于遍历对象添加

defineProperty

的写法更⽅便能被⼤家理解。

我们会将

__ob__

放在

Obrver

中,并且,将判断是否是对象放在

obrve

中,以及是否设置了

__ob__

属性,将

obrve

作为新的⼊⼝⽅

法。

整体的调⽤顺序如图:

上⽂代码

上⽂最终的代码如下:

functiondefineReactive(obj,key,val){

(key);

//判断当前⼊参个数,两个的话直接返回当前层的对象

if(===2){

val=obj[key];

typeofval==='object'&&newObrver(val);

}

Property(obj,key,{

//可枚举,默认为fal

enumerable:true,

//属性的描述符能够被改变,或者是删除,默认为fal

configurable:true,

get(){

returnval;

},

t(newValue){

val=newValue;

typeofval==='object'&&newObrver(val);

}

})

}

//遍历对象当前层的所有属性,并且绑定defineReactive

classObrver{

constructor(obj){

(obj);

}

walk(obj){

letkeys=(obj);

for(leti=0;i<;i++){

defineReactive(obj,keys[i])

}

}

}

__ob__

由于要遍历添加

__ob__

,所以,我们要先改写

Obrver

类,在构造函数中,新增对于

__ob__

属性的构建。

classObrver{

constructor(obj){

Property(obj,'__ob__',{

value:this,

//这个属性仅仅保存Obrver实例,所以不需要遍历

enumerable:fal

})

(obj);

}

//...

}

当然,我们可以对上⾯的代码进⾏⼀定的封装。

functiondef(obj,key,value,enumerable){

Property(obj,key,{

value,

enumerable

})

}

//遍历对象当前层的所有属性,并且绑定defineReactive

classObrver{

constructor(obj){

def(obj,'__ob__',this,fal)

(obj);

}

//...

}

obrve

既然现在有了

__ob__

属性,我们可以根据它是否有

__ob__

属性来判断它是否

newObrver

实例化过,⽽且可以将是否是对象的判断放在

obrve

⽅法中,将它作为⼊⼝⽂件。

现在的执⾏顺序应该是

obrve=>newObrve=>defineReactive

functionobrve(value){

if(typeofvalue!=='object')return;

letob;

//eslint-disable-next-lineno-prototype-builtins

if(Property('__ob__')&&value.__ob__instanceofObrver){

ob=value.__ob__;

}el{

ob=newObrver(value);

}

returnob;

}

由于我们已经将是否对象的判断放⼊了

obrve

中,所以,需要将之前的

typeofval==='object'&&newObrver(val);

改为

obrve(val)

所以,最终的代码如下:

functiondefineReactive(obj,key,val){

(key);

//判断当前⼊参个数,两个的话直接返回当前层的对象

if(===2){

val=obj[key];

obrve(val)

}

Property(obj,key,{

//可枚举,默认为fal

enumerable:true,

//属性的描述符能够被改变,或者是删除,默认为fal

configurable:true,

get(){

returnval;

},

t(newValue){

val=newValue;

obrve(val)

}

})

}

functiondef(obj,key,value,enumerable){

Property(obj,key,{

value,

//这个属性仅仅保存Obrver实例,所以不需要遍历

enumerable

})

}

//遍历对象当前层的所有属性,并且绑定defineReactive

classObrver{

constructor(obj){

def(obj,'__ob__',this,fal)

(obj);

}

walk(obj){

letkeys=(obj);

for(leti=0;i<;i++){

defineReactive(obj,keys[i])

}

}

}

functionobrve(value){

if(typeofvalue!=='object')return;

letob;

//eslint-disable-next-lineno-prototype-builtins

if(Property('__ob__')&&value.__ob__instanceofObrver){

ob=value.__ob__;

}el{

ob=newObrver(value);

}

returnob;

}

下⽂引荐

【⼿把⼿教你搓Vue响应式原理】(四)数组的响应式处理

【⼿把⼿教你搓Vue响应式原理】(五)Watcher与Dep

本文发布于:2022-11-23 08:19:24,感谢您对本站的认可!

本文链接:http://www.wtabcd.cn/fanwen/fan/90/4660.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:observe
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图