当前位置:首页 > VUE

vue数据劫持实现

2026-03-07 21:57:44VUE

Vue 数据劫持的实现原理

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

使用 Object.defineProperty

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

vue数据劫持实现

function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get() {
      console.log(`获取属性 ${key}: ${val}`);
      return val;
    },
    set(newVal) {
      if (newVal === val) 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 改用 Proxy 实现数据劫持,能监听整个对象而非单个属性。

vue数据劫持实现

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) return true;
      console.log(`设置属性 ${key}: ${value}`);
      target[key] = value;
      return true;
    }
  });
}

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: 'Vue' } };
observe(nestedData);
nestedData.user.name = 'React'; // 触发嵌套属性的 setter

数组的劫持

数组需特殊处理,重写变异方法(如 pushpop)。

const arrayProto = Array.prototype;
const arrayMethods = Object.create(arrayProto);
['push', 'pop', 'shift'].forEach(method => {
  arrayMethods[method] = function(...args) {
    console.log(`数组方法 ${method} 被调用`);
    return arrayProto[method].apply(this, args);
  };
});

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

const arr = [1, 2, 3];
observeArray(arr);
arr.push(4); // 触发自定义 push 方法

总结

  • Vue 2.x 使用 Object.defineProperty 劫持对象属性,需递归处理嵌套对象和数组。
  • Vue 3.x 改用 Proxy 实现更全面的劫持,能直接监听整个对象和数组变化。
  • 数组需通过重写原型方法实现劫持,确保变异方法可被监听。

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

相关文章

vue实现登出

vue实现登出

实现Vue登出功能 登出功能通常涉及清除用户会话、令牌或本地存储的数据,并重定向到登录页面。以下是几种常见的实现方式: 清除用户令牌和状态 在Vuex的store中定义一个logout mutati…

vue实现分发

vue实现分发

Vue 实现分发的方法 在 Vue 中,分发(Distribution)通常指的是将内容从父组件传递到子组件,或者通过插槽(Slots)机制让父组件控制子组件的部分渲染内容。以下是几种常见的实现分发的…

vue环境实现

vue环境实现

Vue 环境搭建 安装 Node.js 和 npm Node.js 是运行 Vue 的基础环境,npm 是包管理工具。从 Node.js 官网 下载并安装最新稳定版本。安装完成后,在终端运行以下命令验…

vue实现队列

vue实现队列

Vue 实现队列功能 在 Vue 中实现队列功能可以通过多种方式完成,以下是几种常见的方法: 使用数组模拟队列 队列遵循先进先出(FIFO)原则,可以用数组的 push 和 shift 方法模拟入队…

vue 实现上传

vue 实现上传

Vue 实现文件上传 使用 Vue 实现文件上传可以通过原生 HTML 的 <input type="file"> 或第三方库(如 axios、vue-upload-component)完…

vue ui实现创建vue项目

vue ui实现创建vue项目

使用 Vue UI 创建 Vue 项目 Vue UI 是 Vue CLI 提供的图形化界面工具,可以通过可视化操作创建和管理 Vue 项目。 安装 Vue CLI 确保已安装 Node.js(建议版…