当前位置:首页 > VUE

Vue实现数据响应式

2026-02-25 07:43:34VUE

Vue 数据响应式原理

Vue 的数据响应式是通过 数据劫持 结合 发布-订阅模式 实现的,核心是利用 Object.defineProperty(Vue 2.x)或 Proxy(Vue 3.x)来监听数据变化。

Vue 2.x 实现方式

使用 Object.defineProperty

Vue 2.x 通过 Object.defineProperty 递归地将数据对象的属性转换为 getter/setter,从而在属性被访问或修改时触发更新。

function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function() {
      console.log(`获取 ${key}: ${val}`);
      return val;
    },
    set: function(newVal) {
      if (newVal !== val) {
        console.log(`设置 ${key}: ${newVal}`);
        val = newVal;
        // 触发视图更新
      }
    }
  });
}

const data = { name: 'Vue' };
defineReactive(data, 'name', data.name);
data.name = 'React'; // 触发 setter

数组的特殊处理

Vue 2.x 无法直接监听数组索引变化,因此重写了数组的 pushpopshiftunshiftsplicesortreverse 方法,在调用这些方法时触发更新。

Vue实现数据响应式

const arrayProto = Array.prototype;
const arrayMethods = Object.create(arrayProto);

['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(method => {
  const original = arrayProto[method];
  arrayMethods[method] = function(...args) {
    const result = original.apply(this, args);
    console.log(`数组方法 ${method} 被调用`);
    // 触发视图更新
    return result;
  };
});

Vue 3.x 实现方式

使用 Proxy

Vue 3.x 改用 Proxy 实现响应式,可以直接监听对象和数组的变化,无需特殊处理。

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      console.log(`获取 ${key}: ${target[key]}`);
      return target[key];
    },
    set(target, key, value) {
      if (target[key] !== value) {
        console.log(`设置 ${key}: ${value}`);
        target[key] = value;
        // 触发视图更新
      }
      return true;
    }
  });
}

const data = reactive({ name: 'Vue' });
data.name = 'React'; // 触发 set

响应式工具函数

Vue 3.x 提供了 reactive(对象)和 ref(基本类型)等 API:

Vue实现数据响应式

import { reactive, ref } from 'vue';

const state = reactive({ count: 0 });
const num = ref(1);

state.count++; // 自动触发更新
num.value++;   // 通过 .value 访问

依赖收集与派发更新

依赖收集(Dep)

在 getter 中收集依赖(Watcher),在 setter 中通知依赖更新。

class Dep {
  constructor() {
    this.subscribers = new Set();
  }
  depend() {
    if (currentWatcher) {
      this.subscribers.add(currentWatcher);
    }
  }
  notify() {
    this.subscribers.forEach(watcher => watcher.update());
  }
}

观察者(Watcher)

每个组件实例对应一个 Watcher,负责更新视图。

class Watcher {
  constructor(updateFn) {
    this.updateFn = updateFn;
    this.update();
  }
  update() {
    currentWatcher = this;
    this.updateFn();
    currentWatcher = null;
  }
}

总结

  • Vue 2.x:通过 Object.defineProperty 监听对象属性,重写数组方法。
  • Vue 3.x:通过 Proxy 实现全面监听,支持对象和数组。
  • 核心流程:数据劫持 → 依赖收集 → 派发更新 → 视图渲染。

标签: 数据Vue
分享给朋友:

相关文章

vue实现数据

vue实现数据

Vue 实现数据绑定的方法 Vue.js 提供了多种方式实现数据绑定,包括双向绑定、单向绑定以及动态数据绑定。以下是几种常见的实现方式: 双向数据绑定(v-model) 双向数据绑定通常用于表单元素…

vue怎么实现数据

vue怎么实现数据

Vue 数据实现方式 Vue 提供了多种方式来实现数据的响应式绑定和管理,核心是通过数据驱动视图的更新。 响应式数据声明 在 Vue 组件中,可以通过 data 选项声明响应式数据。这些数据会被 V…

Vue 实现左右滑动

Vue 实现左右滑动

Vue 实现左右滑动的方法 使用 touch 事件监听 通过监听 touchstart、touchmove 和 touchend 事件实现基础滑动逻辑。在 Vue 组件中声明这些事件处理函数,计算滑动…

vue实现数据过滤

vue实现数据过滤

Vue 数据过滤的实现方法 在 Vue 中实现数据过滤可以通过多种方式,以下是几种常见的实现方法: 使用计算属性(Computed Properties) 计算属性是 Vue 中最常用的数据过滤方式…

Vue项目实现rem

Vue项目实现rem

Vue 项目中实现 rem 适配方案 在 Vue 项目中实现 rem 适配,主要目的是让页面元素根据屏幕尺寸自动调整大小。以下是几种常见方法: 使用 postcss-pxtorem 插件 安装 po…

vue实现数据监听

vue实现数据监听

Vue 数据监听实现方式 Vue 提供了多种方式实现数据监听,核心机制基于响应式系统。以下是常见方法: 响应式属性(data 和 computed) 在组件选项中定义 data 返回对象,Vue 会…