当前位置:首页 > VUE

vue 响应式实现

2026-03-08 08:45:04VUE

Vue 响应式实现原理

Vue 的响应式系统通过数据劫持结合发布-订阅模式实现,核心是利用 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);
        val = newVal;
        // 触发依赖更新
        dep.notify();
      }
    }
  });
}

依赖收集 每个属性维护一个 Dep 实例(依赖管理器),在 getter 中收集当前依赖(Watcher):

class Dep {
  constructor() {
    this.subs = [];
  }
  addSub(sub) {
    this.subs.push(sub);
  }
  notify() {
    this.subs.forEach(sub => sub.update());
  }
}

观察者模式 Watcher 实例在初始化时触发 getter,将自身添加到 Dep 中:

class Watcher {
  constructor(vm, key, cb) {
    this.vm = vm;
    this.key = key;
    this.cb = cb;
    Dep.target = this; // 标记当前 Watcher
    this.value = vm[key]; // 触发 getter
    Dep.target = null; // 重置
  }
  update() {
    this.cb.call(this.vm, this.vm[this.key]);
  }
}

Vue 3.x 实现方式

Proxy 代理 使用 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;
    }
  });
}

依赖管理 通过 WeakMapMap 建立靶点(target)与键(key)的依赖关系:

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); // 当前激活的 effect
}

副作用函数 通过 effect 包装响应式操作:

vue 响应式实现

let activeEffect;
function effect(fn) {
  activeEffect = fn;
  fn(); // 执行时触发 track
  activeEffect = null;
}

注意事项

  • 数组处理:Vue 2.x 需重写数组方法(如 pushpop)实现响应式,Vue 3.x 的 Proxy 可直接监听数组变化。
  • 性能优化:Vue 3.x 的 Proxy 减少了递归劫持的开销,并支持懒代理(按需响应)。
  • 嵌套对象:Vue 2.x 需在初始化时递归劫持,Vue 3.x 在访问嵌套属性时才动态代理。

通过上述机制,Vue 实现了数据变化到视图更新的自动同步。

标签: vue
分享给朋友:

相关文章

vue实现flvvideo

vue实现flvvideo

vue-flv-player 实现 FLV 视频播放 安装依赖包 npm install flv.js vue-flv-player 基础组件引入 <template> <v…

vue mvvm实现

vue mvvm实现

Vue MVVM 实现原理 Vue.js 是一个基于 MVVM(Model-View-ViewModel)模式的框架,其核心是通过数据绑定和响应式系统实现视图与数据的自动同步。以下是 Vue 实现 M…

vue实现login

vue实现login

Vue 实现登录功能 在 Vue 中实现登录功能通常需要以下几个步骤: 创建登录表单组件 在 Vue 项目中创建一个登录表单组件,包含用户名和密码输入框以及提交按钮。可以使用 Vue 的模板语法和双…

vue实现 页面

vue实现 页面

Vue 实现页面的核心方法 创建 Vue 项目 使用 Vue CLI 或 Vite 快速初始化项目。Vue CLI 是官方脚手架工具,适合传统项目;Vite 提供更快的现代构建体验。 npm cre…

vue实现修改

vue实现修改

Vue 实现修改功能的方法 在 Vue 中实现修改功能通常涉及表单绑定、状态管理和 API 调用。以下是几种常见实现方式: 双向数据绑定实现表单修改 使用 v-model 指令绑定表单元素与组件数据…

vue实现多线程

vue实现多线程

Vue.js 本身是单线程框架,但可以通过以下方法实现类似多线程的效果或利用浏览器多线程能力: 使用 Web Worker Web Worker 是浏览器提供的多线程 API,适合处理 CPU 密集…