Vue2.0响应式原理

87 阅读2分钟

8Vue2.0响应式原理,使用的是Object.definedProperty进行数据响应式劫持,而Vue3.0使用的是Proxy进行数据据响应式劫持。

下面我做了Vue2.0的原理分析

前言

普通对象的定义,我们是没有办法监听到它的变化,所以普通对象是不具有响应式的,后来有了JS 的Object.definedProperty,这也是为什么Vue不支持IE8以下的版本,因为Object.definedProperty是IE8出来的对象语法,下面让我们一起去了解一下Object.definedProperty这个对象的方法,亲自感受一下Vue2.0的响应式原理的实现过程。

// 这种普通的对象,我们是没办法侦听到对象的改变的,
var obj1 = { a: 1, b: 2 };
obj1.a = 100
// 使用Object.defineProperty定义的对象,具有了get/set钩子,get和set就能侦听一个对象改变和取值,这就具有响应式了。
let obj = {};
let c = 3;
Object.definedProperty(obj2,'c',{
    get() {
        console.log('有人访问了 c');
        return c;
    }
    set(newVal) {
        console.log('有人修改了 c');
        c = newVal;
    }
})
// Vue
// 在这里定义响应式变量
 var data = {
      name: '1',
      pass: '2'
    }
// 第一步:把vue组件中data进行响应式劫持
// 劫持之后,做依赖收集(观察者模式、订阅发布模式),收集“响应式变量->DOM节点”的映射关系
var app = {};
Object.keys(data).forEach(key=> {
    // 所谓的“劫持”,就是给普通对象的属性添加get/set钩子函数
    // 当这个属性被访问时,触发get函数执行
    // 当这个属性的值被修改时,触发set函数执行
     Object.defineProperty(app, key, {
        get() {
          console.log(`你访问了${key}`)
          return data[key]
        },
        set(newVal) {
          console.log(`你修改了${key}`)
          data[key] = newVal
          Watcher()
        }
      })
})
// 第二步:初始化页面(通过Watcher进行页面初始化)
function init() {
     document.getElementById('ipt').addEventListener('input', function(e){
        // 当表单发生变化时,取出表单最新值,更新到响应式变量上
        app.name = e.target.value
      })
      Watcher()
}
init();
 // 第三步:当响应式变量发生变化时,触发set函数执行,再调用Watcher更新DOM
    function Watcher() {
      document.getElementById('ipt').value = app.name
      document.getElementById('h3').innerText = app.name
    }