有使用过vm.$set吗,原理是什么?

开发 前端
vm.$set​ 方法在 Vue 中用于动态添加响应式属性,确保新属性能够被 Vue 的响应式系统监测到。它通过 Object.defineProperty 将新属性定义为响应式属性,并触发依赖更新,确保视图能够正确更新。

vm.$set 是 Vue.js 提供的一个方法,用于在 Vue 实例中动态添加响应式属性。它的主要作用是确保新添加的属性能够被 Vue 的响应式系统监测到,从而触发视图的更新。

使用示例

假设我们有一个 Vue 实例

var vm = new Vue({
  data: {
    user: {
      name: 'Alice'
    }
  }
});

我们希望在 user 对象中添加一个新的属性 age。直接添加不会触发视图更新

vm.user.age = 25; // 直接添加不会触发视图更新

为了确保新添加的属性是响应式的,可以使用 vm.$set

vm.$set(vm.user, 'age', 25);

原理

Vue 的响应式系统是基于 Object.defineProperty 实现的。当一个对象被添加到 Vue 实例的 data 中时,Vue 会递归地遍历该对象的所有属性,并使用 Object.defineProperty 将这些属性转换为 getter 和 setter,从而实现响应式。然而,直接添加的新属性并没有通过这种方式定义,因此 Vue 无法检测到这些新属性的变化。vm.$set 方法内部使用了 Vue 的 set 方法,它会确保新添加的属性也能通过 Object.defineProperty 转换为响应式属性。

vm.$set 的实现

Vue 源码中 set 方法的实现(Vue 2.x)大致如下:

function set(target, key, val) {
  if (Array.isArray(target) && isValidArrayIndex(key)) {
    target.length = Math.max(target.length, key);
    target.splice(key, 1, val);
    return val;
  }
  if (key in target && !(key in Object.prototype)) {
    target[key] = val;
    return val;
  }
  const ob = target.__ob__;
  if (!ob) {
    target[key] = val;
    return val;
  }
  defineReactive(ob.value, key, val);
  ob.dep.notify();
  return val;
}
function defineReactive(obj, key, val) {
  const dep = new Dep();
  let childOb = observe(val);
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter() {
      const value = val;
      if (Dep.target) {
        dep.depend();
        if (childOb) {
          childOb.dep.depend();
        }
      }
      return value;
    },
    set: function reactiveSetter(newVal) {
      const value = val;
      if (newVal === value || (newVal !== newVal && value !== value)) {
        return;
      }
      val = newVal;
      childOb = observe(newVal);
      dep.notify();
    }
  });
}

总结

vm.$set 方法在 Vue 中用于动态添加响应式属性,确保新属性能够被 Vue 的响应式系统监测到。它通过 Object.defineProperty 将新属性定义为响应式属性,并触发依赖更新,确保视图能够正确更新。

使用工具学会使用只是第一步,掌握原理并能够通过原理解决问题才是关键,在平时的开发中,使用时多数,然而在遇到复杂问题或者优化时候掌握原理会提高开发效率。

责任编辑:武晓燕 来源: 海燕技术栈
相关推荐

2022-07-12 12:05:22

JavaSemaphore

2023-11-05 10:52:54

DNS服务器浏览器

2021-09-10 06:50:03

HashMapHash方法

2023-09-13 09:20:00

日志配置Spring

2021-08-26 21:55:38

DPU架构数据

2009-12-07 16:46:56

Windows SDK

2021-09-27 08:02:17

CDN加速网站网络

2024-01-11 08:53:58

2021-02-02 18:02:09

java对象数据

2021-02-08 21:07:47

JavaCAS机制

2021-05-09 09:30:13

Docker操作系统容器

2021-06-30 06:28:07

人脸识别AI人工智能

2024-08-27 08:55:32

Axios底层网络

2024-08-12 12:32:53

Axios机制网络

2021-07-29 11:46:27

NAS存储NAS服务器

2024-04-30 09:02:48

2024-11-11 00:00:01

线程池工具

2021-04-27 18:12:22

WebSocket持久化连接HTTP

2024-04-01 00:00:00

Redis缓存服务消息队列

2020-12-31 05:49:44

FlinkSQL函数
点赞
收藏

51CTO技术栈公众号