当前位置:首页 > VUE

vue响应式的实现

2026-02-24 06:27:55VUE

Vue 响应式原理

Vue 的响应式系统基于 JavaScript 的 Object.defineProperty(Vue 2.x)或 Proxy(Vue 3.x)实现。核心是通过数据劫持结合发布-订阅模式,自动追踪依赖并在数据变化时触发更新。

Vue 2.x 实现方式

数据劫持 使用 Object.defineProperty 递归地将对象的属性转换为 getter/setter,在访问或修改数据时触发依赖收集和更新。

function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    get() {
      console.log(`读取 ${key}: ${val}`);
      return val;
    },
    set(newVal) {
      if (newVal !== val) {
        console.log(`设置 ${key}: ${newVal}`);
        val = newVal;
      }
    }
  });
}

依赖收集 每个响应式属性关联一个 Dep 实例,用于存储依赖(即 Watcher 实例)。在 getter 中收集依赖,在 setter 中通知更新。

class Dep {
  constructor() {
    this.subscribers = [];
  }
  depend() {
    if (target && !this.subscribers.includes(target)) {
      this.subscribers.push(target);
    }
  }
  notify() {
    this.subscribers.forEach(sub => sub());
  }
}

Watcher Watcher 代表一个依赖,在初始化时触发 getter 以收集依赖,数据变化时执行回调。

let target = null;
function watcher(fn) {
  target = fn;
  target();
  target = null;
}

Vue 3.x 实现方式

Proxy 代理 Vue 3 使用 Proxy 替代 Object.defineProperty,能直接监听对象和数组的变化,无需递归遍历。

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      track(target, key);
      return target[key];
    },
    set(target, key, value) {
      target[key] = value;
      trigger(target, key);
    }
  });
}

依赖跟踪与触发 通过 tracktrigger 函数管理依赖关系,原理与 Vue 2.x 类似,但实现更简洁。

const targetMap = new WeakMap();
function track(target, key) {
  let depsMap = targetMap.get(target);
  if (!depsMap) {
    targetMap.set(target, (depsMap = new Map()));
  }
  let dep = depsMap.get(key);
  if (!dep) {
    depsMap.set(key, (dep = new Set()));
  }
  dep.add(activeEffect);
}

function trigger(target, key) {
  const depsMap = targetMap.get(target);
  if (!depsMap) return;
  depsMap.get(key).forEach(effect => effect());
}

响应式系统的局限性

对象新增属性 Vue 2.x 无法检测对象属性的添加或删除,需使用 Vue.setVue.delete。Vue 3.x 通过 Proxy 解决了这一问题。

数组变化 Vue 2.x 通过重写数组方法(如 pushpop)实现响应式,直接通过索引修改或修改长度不会触发更新。Vue 3.x 的 Proxy 支持对数组的全面监听。

vue响应式的实现

总结

Vue 的响应式系统通过数据劫持和依赖管理实现自动更新。Vue 2.x 依赖 Object.defineProperty,需处理一些边界情况;Vue 3.x 改用 Proxy,提供了更完善的响应式支持。

标签: vue
分享给朋友:

相关文章

vue实现微博发布动态

vue实现微博发布动态

使用Vue实现微博发布动态功能 创建Vue组件结构 新建一个WeiboPost.vue组件,包含文本框、图片上传和发布按钮: <template> <div class="we…

vue实现边框

vue实现边框

Vue 实现边框的方法 在 Vue 中实现边框效果可以通过多种方式完成,包括内联样式、CSS 类绑定、动态样式以及使用第三方 UI 库。以下是几种常见的实现方法。 内联样式绑定 使用 Vue 的 :…

vue实现排序

vue实现排序

Vue 实现排序的方法 在 Vue 中实现排序可以通过多种方式完成,以下是一些常见的方法: 使用计算属性排序数组 计算属性非常适合对数据进行排序,因为它会在依赖的数据变化时自动更新。以下是一个示例:…

vue实现节流

vue实现节流

vue实现节流的方法 在Vue中实现节流(throttle)功能,通常用于限制高频事件的触发频率,例如滚动、输入或按钮点击。以下是几种常见的实现方式: 使用Lodash的throttle函数 安装L…

vue实现getapp

vue实现getapp

Vue 中实现全局获取应用实例的方法 在 Vue 3 中,可以通过 getCurrentInstance 方法获取当前组件实例,但需要明确其使用场景和限制。以下是具体实现方式: 方法一:通过 get…

vue单选实现

vue单选实现

Vue 单选实现 在 Vue 中实现单选功能可以通过多种方式完成,以下是几种常见的方法: 使用 v-model 绑定单选按钮 通过 v-model 绑定一个变量,可以实现单选效果。当用户选择不同的选…