vue为什么深度监听能监听到数据

fiy 其他 40

回复

共3条回复 我来回复
  • fiy的头像
    fiy
    Worktile&PingCode市场小伙伴
    评论

    Vue的深度监听能够监听到数据,是因为Vue使用了一种叫做响应式的机制来管理数据。在Vue中,使用了Object.defineProperty()方法来劫持对数据的访问,从而实现了数据的双向绑定和变化的追踪。

    具体来说,当我们在Vue中声明一个数据对象时,Vue会通过遍历这个对象的属性,并使用Object.defineProperty()方法为每个属性生成一个getter和setter。这样,当我们访问这个属性时,Vue会通过getter来返回属性的值,而当我们修改这个属性时,Vue会通过setter来捕捉到修改操作,并及时更新相关的视图。

    而深度监听就是在这个基础上进行了增强。当我们在数据对象中使用了嵌套对象或数组时,Vue会递归地对嵌套的对象或数组中的属性进行深度监听。这样一来,无论是修改了嵌套对象中的属性,还是对数组进行了增删改操作,Vue都能够捕捉到这些变化,并及时更新相关的视图。

    实现深度监听的关键在于递归地监听嵌套对象和数组。当我们修改嵌套对象中的属性时,Vue会通过setter捕获这个修改操作,并对这个属性进行深度监听。同样地,当我们对数组进行了增删改操作时,Vue也会通过特定的方法例如push()、pop()、splice()等来捕获这些操作,并对整个数组进行深度监听。

    通过深度监听,Vue能够实现数据的响应式更新,保证了数据和视图的同步更新。同时,深度监听也给我们提供了便利,使得在数据变化时能够迅速响应并做出相应的处理,提高了开发效率。

    2年前 0条评论
  • 不及物动词的头像
    不及物动词
    这个人很懒,什么都没有留下~
    评论

    Vue.js 中的深度监听是通过使用 vm.$watch 方法进行实现的。Vue.js 使用的是响应式系统来跟踪数据的变化,通过使用 Object.defineProperty 方法来劫持对象的属性,当属性发生变化时,会触发对应的响应式更新。

    在 Vue.js 中,当我们使用 vm.$watch 方法进行深度监听时,实际上是在监听一个对象的所有属性的变化。当对象的属性发生变化时,就会触发对应的回调函数。

    以下是深度监听能监听到数据的几个原因:

    1. 引用类型数据的属性变化会触发响应式更新:当我们对一个对象的属性进行修改时,Vue.js 会自动检测到这个变化,然后触发对应的响应式更新。这意味着,无论对象的属性是在 Vue 实例创建之前还是之后添加的,只要是引用类型的属性发生了变化,都会被深度监听到。

    2. 对象的属性添加和删除也会触发响应式更新:当我们添加或删除一个对象的属性时,Vue.js 也会自动检测到这个变化并触发响应式更新。这意味着,不仅仅是属性值的变化,属性的添加和删除也会被深度监听到。

    3. 数组的变化也会触发响应式更新:Vue.js 中的数组也是经过特殊处理的。当我们通过数组的方法对数组进行修改时,Vue.js 会自动检测到这个变化并触发响应式更新。例如,当我们使用 pushpopsplice 等方法对数组进行修改时,这个变化会被深度监听到。

    4. 对象和数组的嵌套结构也可以被深度监听:深度监听不仅限于一层对象或数组的变化,它可以递归地监听对象和数组的嵌套结构。例如,当对象的属性值是对象或数组时,对嵌套对象或数组的属性进行修改,同样会触发响应式更新。

    5. 深度监听是通过递归实现的:在 Vue.js 中,当我们使用 vm.$watch 进行深度监听时,实际上是通过递归的方式实现的。Vue.js 会遍历对象的所有属性,若属性是对象或数组,则继续递归遍历直到遍历完整个对象树。这种递归的方式确保了深度监听能够监听到所有嵌套的属性的变化。

    2年前 0条评论
  • worktile的头像
    worktile
    Worktile官方账号
    评论

    深度监听是 Vue 框架提供的一种数据监听方式,它能够监听到数据的变化是因为 Vue 在内部对数据进行了劫持和代理。

    在 Vue 中,当一个对象被传入 Vue 实例进行响应式处理时,Vue 内部会通过使用 Object.defineProperty 方法对对象的属性进行劫持。Object.defineProperty 是 JavaScript 提供的一个方法,它可以定义一个对象的属性,并指定该属性的设置和获取方式。

    在劫持过程中,Vue 通过在 get 方法中收集依赖,并在 set 方法中触发依赖更新。当我们使用深度监听时,Vue 会递归地遍历对象的所有属性,对每个属性进行劫持,进而实现了对整个对象及其嵌套属性的监听。

    接下来,我们来看一下深度监听的操作流程。

    1. Vue 实例化

    首先,我们需要将数据传入 Vue 实例进行响应式处理。我们可以通过在 Vue 实例的 data 选项中定义一个对象,并将这个对象传入 Vue 实例。

    var vm = new Vue({
      data: {
        obj: {
          name: 'Vue',
          version: '3.0',
          author: 'Evan You',
        },
      },
    });
    
    1. 对象劫持

    在 Vue 内部,会对传入的对象进行劫持。Vue 利用 Object.defineProperty 方法来定义对象的属性,并为每个属性添加 get 和 set 方法。

    function defineProperty(obj, key, val) {
      Object.defineProperty(obj, key, {
        enumerable: true,
        configurable: true,
        get: function reactiveGetter() {
          // 在这里收集依赖
          return val;
        },
        set: function reactiveSetter(newVal) {
          // 在这里触发依赖更新
          if (newVal === val) return;
          val = newVal;
        },
      });
    }
    
    1. 递归监听

    在劫持过程中,对于对象类型的属性,Vue 会对其属性进行递归监听。这样,就能实现对整个对象及其嵌套属性的深度监听。

    function observe(obj) {
      if (typeof obj !== 'object' || obj === null) {
        return;
      }
    
      Object.keys(obj).forEach(function (key) {
        defineReactive(obj, key, obj[key]);
      });
    }
    
    function defineReactive(obj, key, val) {
      observe(val); // 递归监听子属性
      Object.defineProperty(obj, key, {
        enumerable: true,
        configurable: true,
        get: function reactiveGetter() {
          // 在这里收集依赖
          return val;
        },
        set: function reactiveSetter(newVal) {
          // 在这里触发依赖更新
          if (newVal === val) return;
          val = newVal;
        },
      });
    }
    

    这样,Vue 就能够监听到对象的数据变化了。当我们修改对象的属性时,Vue 会触发相应的 set 方法,从而更新依赖。

    总结一下,深度监听能监听到数据是因为 Vue 在内部对数据进行了劫持和代理。它通过递归遍历对象的属性,对每个属性进行劫持,从而实现了对对象及其嵌套属性的监听。深度监听使得当对象的属性发生变化时,Vue 能够及时地触发相应的更新操作。

    2年前 0条评论
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部