码迷,mamicode.com
首页 > Web开发 > 详细

Vue.js 响应式原理

时间:2019-03-12 09:20:43      阅读:234      评论:0      收藏:0      [点我收藏+]

标签:视图   vue.js   func   getter   ===   tar   构造   收集   更新   

1. Vue2.x 基于 Object.defineProperty 方法实现响应式(Vue3将采用proxy)

Object.defineProperty(obj, prop, descriptor)


2. 定义defineReactive来对对象的属性进行getter、setter操作

function defineReacive(obj, key, val){
    Object.defineProperty(obj, key, {
        enumerable: true,
        configurable: true,
        get() {
            return val;
        },
        set(newVal) {
            if(val === newVal) return;
            val = newVal;
            callback(newVal);
        }
    })
}


3. 我们需要遍历所有数据,所以需要observer方法去观察

function observer(val){
    if(!val || typeof val !== 'object') return;
    Obejct.keys(val).forEach(key => {
        defineReactive(val, key, val(key));
    })
}


4. 模拟Vue构造函数

class MockVue {
    constructor(options) {
        this._data = opations.data;
        observer(this._data);
    }
}


5. 实例化MockVue生成实例对象

let v1 = new MockVue({
    data: { }
})


如何让发生变动时触发相关视图更新,那么我们就需要收集依赖,


6. 订阅者Dep(存放watcher观察者对象)

class Dep {
    constructor() {
        this.subs = [];
    }
    addSub(sub) {
        this.subs.push(sub);
    }
    notify() {
        this.subs.forEach(sub => {
            sub.update();
        })
    }
}


7. 观察者wacher

class Watcher {
    constructor() {
        Dep.target = this;
    }
    update() {
        console.log('update...');
    }
}


8. 修改defineReactive方法

function defineReacive(obj, key, val){
    + const dep = new Dep(); 
    Object.defineProperty(obj, key, {
        enumerable: true,
        configurable: true,
        get() {
            + dep.addSub(Dep.target); 
            return val;
        },
        set(newVal) {
            if(val === newVal) return;
            val = newVal;
            - callback(newVal);
            + dep.notify(); 
        }
    })
}


9. 重写MockVue

class MockVue {
    constructor(options) {
        this._data = options.data;
        observer(this._data);
        new Watcher();               // Dep.target会指向这个watcher对象
        console.log('触发getter');
    }
}


Vue.js 响应式原理

标签:视图   vue.js   func   getter   ===   tar   构造   收集   更新   

原文地址:https://www.cnblogs.com/colima/p/10508913.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有
迷上了代码!