简易版本的数据双向绑定原理,还在详细学习中。。。
-
首先需要一个observe函数监听对象属性,如果不监听,就无法得知修改并触发视图更新,所以监听第一步走起。
// 监听对象属性 function observe(target) { if(target === null && typeof target !== 'object') { // 不是对象或者数组,直接返回 return target } // 重新定义各个属性 for(let key in target) { defineReactive(targer,key,target[key]) } } // 重新定义属性,监听 function defineReactive(target,key,value) { // 深度监听 observer(value) // 核心使用Object.defineProperty() Object.defineProperty(target,key,{ get() { return value }, set(newVal) { if(newVal !== value) { // 监听到变化啦 // 设置新值 value = newVal // 通知更新notify dep.notify(); // 通知所有订阅者 } } }) }深度监听的意义类似这样:
obj: {a:123}value就是{a:123},observe(value)深度监听到obj.a,这样就实现每个数据的监听啦~ 所以是利用Object.defineProerty()的getter和setter来对数据进行劫持(getter收集依赖,setter派发更新) -
实现一个消息收集器,把监听到的数据收集在一个数组中,数据变动触发notify,再调用订阅者的update
function defineReactive(target,key,value) { var dep = new Dep(); // 深度监听 observer(value) // 核心使用Object.defineProperty() Object.defineProperty(target,key,{ get() { return value }, set(newVal) { if(newVal !== value) { // 监听到变化啦 // 设置新值 value = newVal // 通知更新notify dep.notify(); // 通知所有订阅者 } } }) } // 这里模拟处理了一下,是这个流程,伪代码 class Dep { constructor() { this.sub = [] } addSub(sub) { this.sub.push(sub) } notify() { this.sub.forEach(sub => { sub.update() }) } }
大致流程是这个样子。乞丐版的响应式原理,其实只涉及到,dep和observe,watch的代码未实现,后期努力学习补上。看到一篇文章介绍的更为详细,如果大家想深入学习,推荐看这个呀vue双向数据绑定原理