当前位置:首页 > VUE

vue怎么实现数据劫持

2026-01-20 13:40:12VUE

Vue 数据劫持的实现原理

Vue 的数据劫持主要通过 Object.definePropertyProxy 实现,用于监听数据变化并触发视图更新。

使用 Object.defineProperty(Vue 2.x)

Object.defineProperty 是 Vue 2.x 的核心实现方式,通过劫持对象的属性访问和修改。

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

const data = {};
defineReactive(data, 'message', 'Hello Vue');
data.message; // 触发 getter
data.message = 'Updated'; // 触发 setter

使用 Proxy(Vue 3.x)

Vue 3.x 改用 Proxy 实现数据劫持,能监听整个对象而非单个属性,支持数组和嵌套对象。

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key, receiver) {
      console.log(`读取属性 ${key}`);
      return Reflect.get(target, key, receiver);
    },
    set(target, key, value, receiver) {
      console.log(`设置属性 ${key}: ${value}`);
      return Reflect.set(target, key, value, receiver);
    }
  });
}

const data = reactive({ message: 'Hello Vue' });
data.message; // 触发 get
data.message = 'Updated'; // 触发 set

嵌套对象的劫持

递归处理嵌套对象以确保深层属性也能被监听。

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

  Object.keys(obj).forEach(key => {
    defineReactive(obj, key, obj[key]);
    observe(obj[key]); // 递归劫持嵌套属性
  });
}

const nestedData = { user: { name: 'Alice' } };
observe(nestedData);
nestedData.user.name = 'Bob'; // 触发嵌套属性的 setter

数组的劫持

Vue 2.x 通过重写数组的变异方法(如 pushpop)实现监听。

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) {
    console.log(`数组方法 ${method} 被调用`);
    return original.apply(this, args);
  };
});

function observeArray(arr) {
  arr.__proto__ = arrayMethods;
  arr.forEach(item => observe(item));
}

const arr = [1, 2, 3];
observeArray(arr);
arr.push(4); // 触发拦截

总结

  • Vue 2.x 使用 Object.defineProperty 劫持对象属性,需递归处理嵌套对象和重写数组方法。
  • Vue 3.x 使用 Proxy 直接监听整个对象,简化实现并支持更多场景。
  • 数据劫持的核心目的是在数据变化时触发依赖更新(如视图渲染)。

vue怎么实现数据劫持

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

相关文章

vue实现适老化样式

vue实现适老化样式

Vue 实现适老化样式的关键方法 全局字体与字号调整 通过 CSS 变量或主题配置统一放大基础字号,建议正文不小于 18px,标题更大。在 App.vue 中设置全局样式: :root { --…

vue怎么实现选中删除

vue怎么实现选中删除

实现选中删除功能的方法 在Vue中实现选中删除功能通常涉及以下几个关键步骤: 数据绑定与选中状态管理 使用v-model或v-for指令绑定列表数据,结合复选框或单选按钮实现选中状态管理。例如:…

vue实现列表显示

vue实现列表显示

Vue 实现列表显示的方法 在 Vue 中实现列表显示通常使用 v-for 指令,结合数组或对象数据渲染动态列表。以下是几种常见的实现方式。 基本列表渲染 通过 v-for 指令遍历数组,动态生成列…

vue设计与实现目录

vue设计与实现目录

以下是《Vue设计与实现》一书的典型目录结构(根据常见技术书籍及Vue核心内容整理): 响应式系统 响应式数据的基本原理 依赖收集与触发更新 实现简易响应式系统 Proxy与Refle…

vue实现用户信息删除

vue实现用户信息删除

Vue 实现用户信息删除功能 在 Vue 中实现用户信息删除功能通常涉及前端界面交互和后端 API 调用。以下是实现步骤: 前端界面设计 创建删除按钮或操作项,通常使用 @click 事件触发删除操…

实现 vue ssr

实现 vue ssr

Vue SSR 实现方法 Vue SSR(Server-Side Rendering)通过服务器端渲染 Vue 应用,提升首屏加载速度和 SEO 友好性。以下是核心实现方法: 基础配置 安装必要…