We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在js引擎执行渲染函数的途中,突然读到了data.msg,data已经被定义成了响应式数据,读取data.msg时所触发的get函数已经被我们劫持,这个get函数中我们去记录下data.msg被这个渲染函数所依赖,然后再返回data.msg的值。
处理对象,将对象定义为响应式;修改data每个属性的get函数,进行拦截;
import Dep from "./dep" import { isObject } from "./utils" export default function reactive( data ){ if(isObject(data)){ Object.keys(data).forEach(key => { defineReactive(data, key); }) } return data; }; function defineReactive(data, key){ let val = data[key]; var dep = new Dep(); Object.defineProperty(data, key,{ get(){ dep.depend(); return val; }, set( newVal ){ val = newVal; console.log(dep) dep.notify();//触发更新 } }); //如果值也是引用类型对象,也要处理为响应式 if(isObject(val)){ reactive( val ) } }
那么,get函数里的dep又是什么呢?
可以把dep看成一个收集依赖的小筐,每当运行渲染函数读取到data的某个key的时候,就把这个渲染函数丢到这个key自己的小筐中,在这个key的值发生改变的时候,去key的筐中找到所有的渲染函数再执行一遍。
就是说,我们在遍历data属性修改get函数的时候,我们把有涉及到当前属性的渲染函数的watcher添加到dep这个“小筐”中;
export default class Dep { constructor(){ this.deps = new Set(); } depend(){ if(Dep.target){ this.deps.add(Dep.target) } } notify(){ this.deps.forEach(watcher => { watcher.update(); }) } } Dep.target = null
Dep.target这个概念也是Vue中所引入的,它是一个挂在Dep类上的全局变量
Dep.target 存储了渲染函数的watcher,接下来就是watcher的实现,Watcher在实例化的时候,将当前watcher存储到Dep.target;
new Watcher(() => { document.getElementById('app').innerHTML = `msg is ${data.msg}` })
Dep.target存储
const targetStack = []; // 将上一个watcher推到栈里,更新Dep.target为传入的_target变量。 export function pushTarget(_target){ if(Dep.target) targetStack.push(Dep.target); Dep.target = _target } // 取回上一个watcher作为Dep.target,并且栈里要弹出上一个watcher。 export function popTarget(){ Dep.target = targetStack.pop(); }
Watcher实现:
import Dep, {pushTarget, popTarget } from "./dep" export default class Watcher { constructor( getter ){ this.getter = getter; this.get(); } get(){ pushTarget(this); this.value = this.getter(); popTarget(); return this.value } update(){ this.get(); } }
所以,当data属性值在发送改变是,set函数中会执行dep.notify();遍历deps中的每个watcher,执行update; 就这样,响应式就实现了。
参考
The text was updated successfully, but these errors were encountered:
No branches or pull requests
reactive
处理对象,将对象定义为响应式;修改data每个属性的get函数,进行拦截;
Dep
那么,get函数里的dep又是什么呢?
就是说,我们在遍历data属性修改get函数的时候,我们把有涉及到当前属性的渲染函数的watcher添加到dep这个“小筐”中;
watcher
Dep.target 存储了渲染函数的watcher,接下来就是watcher的实现,Watcher在实例化的时候,将当前watcher存储到Dep.target;
Dep.target存储
Watcher实现:
所以,当data属性值在发送改变是,set函数中会执行dep.notify();遍历deps中的每个watcher,执行update;
就这样,响应式就实现了。
参考
The text was updated successfully, but these errors were encountered: