当前位置:首页 > VUE

vue响应式实现

2026-02-25 14:38:47VUE

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}`);
      return val;
    },
    set(newVal) {
      if (newVal !== val) {
        console.log(`修改 ${key} 为 ${newVal}`);
        val = newVal;
      }
    }
  });
}

依赖收集 每个响应式属性关联一个 Dep(依赖管理器),在 getter 中收集依赖(Watcher),在 setter 中通知依赖更新。

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

let target = null;
function watchEffect(effect) {
  target = effect;
  effect();
  target = null;
}

Vue 3.x 实现方式

Proxy 代理 使用 Proxy 拦截对象的整个操作(包括新增/删除属性),无需递归遍历对象。

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);
      return true;
    }
  });
}

依赖跟踪与触发 通过 tracktrigger 函数管理依赖关系,替代 Vue 2.x 的 DepWatcher

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 中直接通过 obj.newKey = value 添加的属性不是响应式的,需使用 Vue.setthis.$set

数组变更检测 Vue 2.x 无法检测以下数组变动:

  • 通过索引直接设置项(如 arr[0] = newValue
  • 修改数组长度(如 arr.length = 0

解决方案是使用数组的变异方法(如 pushpop)或 Vue.set

性能优化建议

  • 避免频繁操作大型响应式对象。
  • 对于不需要响应式的数据,使用 Object.freeze 冻结。
  • 在 Vue 3.x 中,使用 shallowReactive 处理嵌套层级较浅的对象。

通过上述机制,Vue 实现了数据与视图的自动同步,开发者只需关注数据逻辑,无需手动操作 DOM。

vue响应式实现

标签: vue
分享给朋友:

相关文章

vue 移动端实现签名

vue 移动端实现签名

Vue 移动端签名实现方法 在移动端实现签名功能,可以通过HTML5的Canvas结合触摸事件完成。以下是具体实现步骤: 使用Canvas绘制签名 安装vue-signature-pad插件或直接使…

vue实现关键词轮播

vue实现关键词轮播

Vue 实现关键词轮播 基础实现方案 使用 Vue 的 v-for 和 setInterval 实现基础轮播效果: <template> <div class="keywor…

vue实现主题

vue实现主题

Vue 实现主题的方法 使用 CSS 变量动态切换主题 定义全局 CSS 变量,通过修改这些变量实现主题切换。在 Vue 的根组件或全局样式中定义变量: :root { --primary-c…

实现简易vue

实现简易vue

实现简易 Vue 的核心思路 Vue 的核心功能包括数据响应式、模板编译和虚拟 DOM。以下是一个简易实现方案,涵盖核心功能模块。 数据响应式系统 通过 Object.defineProperty…

vue实现键盘

vue实现键盘

Vue 实现键盘功能 在Vue中实现键盘功能通常涉及监听键盘事件、处理输入以及渲染虚拟键盘界面。以下是几种常见的实现方式: 监听键盘事件 通过@keydown或@keyup指令监听键盘事件,适用于需…

vue 实现后退

vue 实现后退

实现后退功能的方法 在Vue中实现后退功能通常需要结合浏览器历史记录API或Vue Router的导航方法。以下是几种常见的实现方式: 使用Vue Router的go方法 this.$router…