[Vue]响应式机制自实现

响应式机制

在Vue文档的深入响应式机制中,提到Vue基于ES5的Object.defineProperty实现了其响应机制,并给出了它的逻辑结构图。

理论上,每一个Vue组件实例拥有一个Watcher实例,其逻辑图为:
这里写图片描述

挺有意思的,在看源码前,自己照着个图实现了一下。

Watcher
class Watcher{
    constructor(el){
        this.el = el;
        this.data = undefined;
        this.dependency = undefined;
    }
    setData(data,dependency){
        this.data = data;
        this.dependency = dependency;
        this.bind();
        this.init();
    }
    bind(){
        let self = this;
        Object.keys(self.data).forEach(key => {
            let value = self.data[key];
            const dm = new DepManager();
            dm.register(self);
            Object.defineProperty(self.data, key, {
                get(){
                    for(let dep of self.dependency){
                        dm.collect(dep);
                    }
                    return value;
                },
                set(newValue){
                    value = newValue;
                    dm.notify();
                }
            });
        });
    }
    // 初始化界面渲染效果
    init(){
        let self = this;
        for(let dep of self.dependency){
            this.render(dep)
        }
    }
    // 渲染函数
    render(func){
        // 相应的渲染方法
        document.getElementById(this.el).innerHTML=func();
    }
}
依赖管理
// 依赖管理者
class DepManager{
    constructor(){
        // 依赖的方法
        this.dependency = [];
        // 该属性的相关依赖的订阅者
        this.subscribers = [];
    }
    // 注册订阅者
    register(sub){
        if(!this.subscribers.includes(sub))
            this.subscribers.push(sub);
    }
    // 收集依赖
    collect(dependency){
        if(!this.dependency.includes(dependency))
            this.dependency.push(dependency);
    }
    // 通知更新
    notify(){
        let self = this;
        this.dependency.forEach( dep => {
            self.subscribers.forEach( sub => sub.render(dep));
        });
    }
};
实例化
var data = { a:2, b:3 };
var me = new Watcher('test'); // 绑定
  
  
me.setData(data,[()=>data.a*data.b])
效果演示

这里写图片描述

猜你喜欢

转载自blog.csdn.net/Shenpibaipao/article/details/81812136