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 响应式原理
原文地址:https://www.cnblogs.com/colima/p/10508913.html