手写Vue数据响应式原理
程序员文章站
2022-06-09 17:08:56
...
手写Vue数据响应式原理
// 判断是否是对象
function isObserve(obj){
// 因为null 也是object typeof null ====》'object'
return obj !== null && !Array.isArray(obj) && typeof obj === 'object'
// 返回布尔值 如果是对象返回true
}
function observe(obj){
if(!isObserve(obj)){
// 不处理非对象
return;
}
// 遍历对象的每一个属性
Object.keys(obj).forEach((key)=>{
var dep = new Dep()
// 重新定义属性
var internalValue = obj[key];
observe(internalValue);
Object.defineProperty(obj,key,{
get(){
// 看一下那个函数用到了我这个属性,将该函数记录下来
dep.depend();
return internalValue;
},
set(val){
observe(val)
internalValue = val;
// 通知所有用到我这个属性的,全部重新运行
dep.notify()
}
})
})
}
/**
* 定义一个构造函数,用于是谁在依赖
*/
function Dep(){
// new 一个Set,一个元素不可重复的数组,用于记录依赖
this.subscribes = new Set();
}
Dep.prototype.depend = function(){
// 判断存不存在,如果存在,就记录在依赖数组中
if(activeUpdate){
this.subscribes.add(activeUpdate)
}
}
Dep.prototype.notify = function(){
// 将activeUpdate数组拿出来,然后循环执行就好了
this.subscribes.forEach(fn => fn())
}
// 当前正在收集依赖的函数
var activeUpdate = null;
/**
* 自动运行指定函数
* @param {*} fn
*/
function autorun(fn){
function Wrapper(){
activeUpdate = Wrapper;
// 该函数的运行期间,activeUpdate一定有值
fn();
activeUpdate = null;
}
Wrapper()
}
var state = {
name: 'diudiu',
age: 18,
addr: {
province: "四川",
city: '成都'
},
};
observe(state)
autorun(()=>{
if(state.age%2!==0){
console.log("姓名", state.name, "地址", state.addr.province, state.addr.city);
}
})
state.age = 19;
// -->姓名 diudiu 地址 四川 成都
state.name = '勾勾'
// --> 姓名 勾勾 地址 四川 成都
state.addr.province = "上海";
// --> 姓名 勾勾 地址 上海 成都
state.addr.city = "南京";
// --> 姓名 勾勾 地址 上海 南京
上一篇: html之百度地图接口的使用(代码实例)
下一篇: Centos7环境下YUM的搭建方法