vue2数据驱动响应原理
前言
vue2 mvvm数据驱动响应原理
一、入口文件
// index.js
import observe from './observe.js';
let obj={
a:{
m:{
n:5
}
},
b:10,
c:{
d:{
e:{
f:999
}
}
}
};
//将整个对象变成可侦测的
observe(obj);
obj.a;
console.log(obj.c.d.e)
obj.b='bbbb222';
console.log(obj.b);
二、将整个对象变成可侦测的
1.为每一个层级的对象加上.__ob__属性,标识是可以侦测的对象,在这个对象中实现getter、setter监听
// observer.js
import Observer from './Observer.js';
export default function(value){
console.log('进入observe函数中。')
//如果value不是对象就什么都不做
if(typeof value != 'object') return;
//如果是 判断是否有__ob__属性
let ob;
if(value.__ob__ !=undefined){
ob = value.__ob__;
}else{
ob = new Observer(value);
}
return ob
}
2.为被侦测对象加属性和getter、settter
代码如下(示例):
// Observer.js
import def from './utils.js';
import defineReactive from './defineReactive.js';
export default class Observer{
constructor(value){
console.log('进入类Observer类中');
//给实例(this表示实例,值的注意的是构造函数中的this是表示实例)加上属性,值是这次new的实例
def(value,'__ob__',this,false);
//不要忘记初心Observer类的目的是:将一个正常的objext对象转换成每个层级的属性都是响应式的(可被侦测的)的object
this.walk(value);
};
//遍历对象
walk(value){
for(let key in value){
defineReactive(value,key);
}
}
}
// utils.js
export default function def(obj,key,value,enumerable){
Object.defineProperty(obj,key,{
value,
enumerable,
configurable:true,
writable:true
})
}
// defineReactive.js
import observe from './observe.js'
export default function defineReactive(obj,key,value){
console.log('我是defineReacytive函数:',key);
if(arguments.length==2){
value = obj[key];
};
//重要:当子元素形成observe时候,形成递归,这个递归不是自己调用自己,而是多个函数的循环调用
let childrenOb = observe(value);
Object.defineProperty(obj,key,{
// 可枚举
enumerable:true,
// 可配置
configurable:true,
//getter
get(){
console.log('正在试图访问'+key+'属性');
return value;
},
//setter
set(newValue){
console.log('正在试图设置'+key+'属性');
if(value===newValue)return;
value =newValue;
//当设置新值时候,新值也需要被observe,因为新值可能也是对象
childrenOb = observe(newValue)
return true
}
})
}
三、递归关键点
- 当子元素形成observe时候,形成递归,这个递归不是自己调用自己,而是多个函数的循环调用
- 当设置新值时候,新值也需要被observe,因为新值可能也是对象