返回

简单手写vue3响应式原理

前端

在之前的文章里,我介绍了 Vue2 的响应式原理。在评论中,有掘友评论想让我介绍 Vue3 的响应式原理。那么在这篇文章中,我将带领大家来简单手写一下 Vue3 中的几个响应式 API。

一、Vue3 响应式原理概述

Vue3 的响应式原理与 Vue2 有所不同。Vue2 使用的是 数据劫持 的方式来实现响应式,而 Vue3 使用的是 Proxy API 来实现响应式。

Proxy API 是 JavaScript 中的一个新特性,它允许我们创建一个代理对象,这个代理对象可以拦截对目标对象的访问和操作。当代理对象被访问或操作时,我们可以对这些访问和操作进行自定义处理。

Vue3 就是利用 Proxy API 来实现响应式的。它通过创建一个代理对象来包装数据对象,当数据对象被访问或操作时,代理对象就会拦截这些访问和操作,并触发相应的更新操作。

二、手写 Vue3 响应式 API

为了更好地理解 Vue3 的响应式原理,我们接下来将简单手写一下 Vue3 中的几个响应式 API。

1. reactive()

reactive() 函数是 Vue3 中的一个响应式 API,它可以将一个普通对象转换为一个响应式对象。当响应式对象被访问或操作时,就会触发相应的更新操作。

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      // 当读取响应式对象的属性时触发
      // 在这里我们可以做一些自定义处理,比如记录属性的访问次数等
      console.log(`get ${key}`);
      return Reflect.get(target, key);
    },
    set(target, key, value) {
      // 当设置响应式对象的属性时触发
      // 在这里我们可以做一些自定义处理,比如触发更新操作等
      console.log(`set ${key} to ${value}`);
      Reflect.set(target, key, value);
      // 触发更新操作
      trigger(target, key);
    }
  });
}

2. ref()

ref() 函数是 Vue3 中的另一个响应式 API,它可以将一个普通值转换为一个响应式值。当响应式值被访问或操作时,就会触发相应的更新操作。

function ref(value) {
  return reactive({ value });
}

3. computed()

computed() 函数是 Vue3 中的一个计算属性 API,它可以将一个函数转换为一个响应式属性。当计算属性的依赖项发生变化时,计算属性的值就会重新计算并更新。

function computed(getter) {
  let value;
  let dirty = true;
  return {
    get() {
      if (dirty) {
        // 计算属性的值发生变化,重新计算并更新
        value = getter();
        dirty = false;
      }
      return value;
    },
    set(newValue) {
      value = newValue;
      // 触发更新操作
      trigger(this, 'value');
    }
  };
}

4. watch()

watch() 函数是 Vue3 中的一个侦听器 API,它可以监听一个响应式属性的变化。当响应式属性发生变化时,侦听器函数就会被触发。

function watch(target, key, callback) {
  // 获取响应式对象的属性值
  let oldValue = Reflect.get(target, key);
  // 创建一个侦听器函数
  let listener = function(newValue) {
    // 判断属性值是否发生变化
    if (newValue !== oldValue) {
      // 属性值发生变化,触发回调函数
      callback(newValue, oldValue);
      // 更新旧值
      oldValue = newValue;
    }
  };
  // 添加侦听器
  target.__watchers.push(listener);
  // 返回一个取消侦听的函数
  return () => {
    // 移除侦听器
    target.__watchers.splice(target.__watchers.indexOf(listener), 1);
  };
}

三、总结

本文简单介绍了 Vue3 的响应式原理,并手写了 Vue3 中的几个响应式 API。通过这些 API,我们可以实现数据响应式,从而让我们的组件能够自动更新。