理解vue的响应式原理、双向绑定原理、虚拟dom

三者关系

Vue的响应式原理、双向绑定、虚拟DOM之间是一种协同工作的关系,它们共同构成了Vue框架的核心特性,用于实现数据驱动的视图更新。

  • 响应式原理为基础: 响应式原理是Vue实现数据和视图关联的基础,确保数据的变化能够被观察到。

  • 双向绑定建立在响应式基础上: 双向绑定通过v-model等指令建立在响应式系统的基础上,使得视图和数据之间能够实现双向同步。

  • 虚拟DOM优化性能: 虚拟DOM作为性能优化的手段,通过比对新旧虚拟DOM,最小化对实际DOM的操作,提高了页面渲染的效率。

这三者相互协同工作,使得Vue能够高效地实现数据驱动的视图更新,同时确保了开发者能够以简洁的方式处理复杂的用户界面逻辑。

详解

1、响应式原理

数据驱动视图。数据变化,页面也跟着变化。

Vue2.x是借助Object.defineProperty()实现的,而Vue3.x是借助Proxy实现的

1、vue2.xObject.defineProperty()

Object.defineProperty(obj, key, {
    enumerable: true,//控制属性是否会出现在对象的属性枚举中
    configurable: true,//控制属性的可配置性,即是否可以使用 Object.defineProperty 修改属性的特性,是否可以删除属性。
    //拦截get,当我们访问data.key时会被这个方法拦截到
    get: function getter () {
        //我们在这里收集依赖
        return obj[key];
    },
    //拦截set,当我们为data.key赋值时会被这个方法拦截到
    set: function setter (newVal) {
        //当数据变更时,通知依赖项变更UI
    } 
})

Object.defineProperty 允许定义一个对象属性,其中包含 getter setter 函数。getter 在每次访问属性时触发,setter 在每次修改属性时触发。

当我们通过obj.aobj['a'] 获取属性时,getter 函数会执行,且收集到一个集合中。这样,当属性的值发生变化时,就知道哪些地方依赖于这个属性,需要进行相应的更新。

当我们给属性赋值时,setter 函数会触发。在这个函数中,我们通知之前收集的依赖进行更新,确保数据的变更能够驱动视图的变更。这样就实现了 数据驱动视图
2、vue3.x使用的是Proxy ,与vue2.x思想一致,
Proxy 的优势在于它提供了更强大和灵活的拦截能力,相比于 Object.defineProperty,它可以直接代理整个对象,而不需要像前者一样对每个属性进行处理。这使得 Vue 3.x 的响应式系统更加高效、灵活

// 创建一个响应式对象
function reactive(obj) {
  return new Proxy(obj, {
    get(target, key, receiver) {
      console.log(`Getter: ${key}`);
      const value = Reflect.get(target, key, receiver);
      // 如果属性值是对象,递归地返回代理对象
      return typeof value === 'object' ? reactive(value) : value;
    },
    set(target, key, value, receiver) {
      console.log(`Setter: ${key}`);
      // 使用 Reflect.set 设置属性值
      const result = Reflect.set(target, key, value, receiver);
      // 触发更新
      // 这里可以加上通知更新的逻辑,例如触发重新渲染
      return result;
    }
  });
}

2、双向绑定

Vue的双向绑定是指数据模型Model和视图View之间的同步关系是双向的,当一个改变时,另一个也会相应地发生变化。在Vue中,最常见的双向绑定是通过v-model指令实现的,通常用于表单元素(如