当前位置:首页 > VUE

vue响应式简单实现

2026-02-24 13:04:00VUE

响应式原理概述

Vue的响应式系统通过数据劫持结合发布-订阅模式实现。核心是利用Object.defineProperty(Vue 2)或Proxy(Vue 3)拦截对象属性的读写操作,在数据变化时自动触发依赖更新。

vue响应式简单实现

Vue 2 实现方式

基于Object.defineProperty实现数据劫持:

function defineReactive(obj, key, val) {
  // 递归处理嵌套对象
  observe(val);
  const dep = new Dep(); // 依赖管理

  Object.defineProperty(obj, key, {
    get() {
      Dep.target && dep.addSub(Dep.target); // 收集依赖
      return val;
    },
    set(newVal) {
      if (newVal === val) return;
      observe(newVal); // 新值为对象时递归劫持
      val = newVal;
      dep.notify(); // 通知更新
    }
  });
}

function observe(obj) {
  if (typeof obj !== 'object' || obj === null) return;
  new Observer(obj);
}

class Observer {
  constructor(obj) {
    if (Array.isArray(obj)) {
      // 数组响应式需特殊处理(重写方法)
    } else {
      Object.keys(obj).forEach(key => defineReactive(obj, key, obj[key]));
    }
  }
}

依赖管理类

class Dep {
  constructor() {
    this.subs = [];
  }
  addSub(sub) {
    this.subs.push(sub);
  }
  notify() {
    this.subs.forEach(sub => sub.update());
  }
}
Dep.target = null; // 静态属性指向当前Watcher

Vue 3 实现方式

基于Proxy的改进方案:

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key, receiver) {
      track(target, key); // 依赖收集
      return Reflect.get(target, key, receiver);
    },
    set(target, key, value, receiver) {
      Reflect.set(target, key, value, receiver);
      trigger(target, key); // 触发更新
      return true;
    }
  });
}

// 依赖跟踪与触发
const targetMap = new WeakMap();
function track(target, key) {
  if (!activeEffect) return;
  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());
}

简单Watcher实现

let activeEffect;
class Watcher {
  constructor(fn) {
    this.fn = fn;
    this.run();
  }
  run() {
    activeEffect = this.fn;
    this.fn();
    activeEffect = null;
  }
  update() {
    this.run();
  }
}

// 使用示例
const data = reactive({ count: 0 });
new Watcher(() => console.log('Count:', data.count));
data.count++; // 自动触发日志输出

注意事项

  1. 性能优化:Proxy相比Object.defineProperty无需递归初始化所有属性,按需响应。
  2. 数组处理:Vue 2需重写数组方法(push/pop等),Vue 3的Proxy可直接拦截数组索引变化。
  3. 局限性:Vue 2无法检测新增/删除属性(需用Vue.set/Vue.delete),Proxy无此限制。

通过上述代码可实现基础的响应式系统,实际Vue源码还包含虚拟DOM、批量更新等优化逻辑。

vue响应式简单实现

标签: 简单vue
分享给朋友:

相关文章

vue设计与实现 书

vue设计与实现 书

vue设计与实现 书 《Vue.js设计与实现》是一本深入探讨Vue.js框架内部原理和设计思想的书籍,适合希望深入理解Vue.js的开发者。以下是关于这本书的详细信息: 书籍内容 《Vue…

vue设计与实现下载

vue设计与实现下载

vue设计与实现电子书下载 《Vue.js设计与实现》是一本深入解析Vue.js框架原理的书籍,由霍春阳(HcySunYang)撰写。以下是获取该资源的常见途径: 正版购买渠道 京东、当当、天…

vue实现a

vue实现a

Vue 实现 A 功能的方法 在 Vue 中实现 A 功能可以通过多种方式,具体取决于 A 功能的具体需求。以下是几种常见的实现方法: 使用 Vue 组件 通过创建自定义组件来实现 A 功能。组件可…

vue element实现

vue element实现

Vue Element UI 实现 Vue Element UI 是基于 Vue.js 的组件库,提供丰富的 UI 组件,适合快速开发企业级中后台产品。以下是一些关键实现方法和步骤: 安装 Vue…

vue 实现级联

vue 实现级联

Vue 实现级联选择器 级联选择器(Cascader)常用于省市区选择、分类选择等场景。Vue 中可以通过 Element UI、Ant Design Vue 等 UI 库实现,也可以手动封装。…

vue 实现拖动

vue 实现拖动

Vue 实现拖动的几种方法 在Vue中实现拖动功能可以通过多种方式,包括原生HTML5的拖放API、第三方库如vuedraggable等。以下是几种常见的实现方法: 使用HTML5拖放API HTM…