当前位置:首页 > VUE

vue数据劫持实现

2026-02-10 22:08:08VUE

Vue 数据劫持实现原理

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

使用 Object.defineProperty

Object.defineProperty 是 Vue 2.x 的核心实现方式,通过对对象属性的劫持实现响应式。

function defineReactive(obj, key, val) {
  // 递归处理嵌套对象
  observe(val);

  Object.defineProperty(obj, key, {
    get() {
      console.log(`get ${key}: ${val}`);
      return val;
    },
    set(newVal) {
      if (newVal !== val) {
        console.log(`set ${key}: ${newVal}`);
        observe(newVal); // 处理新值为对象的情况
        val = newVal;
      }
    }
  });
}

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

  Object.keys(obj).forEach(key => {
    defineReactive(obj, key, obj[key]);
  });
}

// 测试
const data = { foo: 'foo', bar: { a: 1 } };
observe(data);
data.foo; // 输出: get foo: foo
data.foo = 'new foo'; // 输出: set foo: new foo
data.bar.a; // 输出: get a: 1

使用 Proxy

Vue 3.x 改用 Proxy 实现,能直接监听整个对象而非属性,且支持数组变化监听。

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

  const observed = new Proxy(obj, {
    get(target, key, receiver) {
      console.log(`get ${key}`);
      const result = Reflect.get(target, key, receiver);
      return reactive(result); // 递归代理嵌套对象
    },
    set(target, key, val, receiver) {
      console.log(`set ${key}: ${val}`);
      return Reflect.set(target, key, val, receiver);
    },
    deleteProperty(target, key) {
      console.log(`delete ${key}`);
      return Reflect.deleteProperty(target, key);
    }
  });

  return observed;
}

// 测试
const data = reactive({ foo: 'foo', bar: { a: 1 } });
data.foo; // 输出: get foo
data.foo = 'new foo'; // 输出: set foo: new foo
data.bar.a; // 输出: get bar -> get a

数组劫持的特殊处理

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) {
    const result = original.apply(this, args);
    console.log(`Array ${method}: ${args}`);
    // 触发更新逻辑
    return result;
  };
});

function observeArray(arr) {
  arr.__proto__ = arrayMethods;
}

// 测试
const arr = [];
observeArray(arr);
arr.push(1); // 输出: Array push: 1

总结

  • Vue 2.x:基于 Object.defineProperty,需递归遍历对象属性,对数组需特殊处理。
  • Vue 3.x:基于 Proxy,可拦截整个对象操作,无需递归初始化,性能更好。

vue数据劫持实现

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

相关文章

vue设计与实现 书

vue设计与实现 书

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

vue实现视频会议

vue实现视频会议

使用 Vue 实现视频会议 技术选型 Vue.js 作为前端框架,结合 WebRTC 技术实现实时音视频通信。常用的库包括: peerjs:简化 WebRTC 的点对点连接。 socket.io:用…

vue实现一个tab栏

vue实现一个tab栏

Vue 实现 Tab 栏 基础实现(选项式 API) <template> <div class="tab-container"> <div class="t…

代码实现vue

代码实现vue

创建Vue项目 使用Vue CLI快速初始化项目,确保已安装Node.js和npm/yarn: npm install -g @vue/cli vue create my-vue-project…

vue怎么实现

vue怎么实现

Vue 实现方法 Vue 是一个流行的前端框架,用于构建用户界面。以下是几种常见的实现方法: 数据绑定 使用 v-model 指令实现双向数据绑定,适用于表单输入元素。 <input v…

vue实现erp

vue实现erp

Vue实现ERP系统的关键步骤 技术选型与架构设计 采用Vue 3 + TypeScript构建前端,搭配Pinia状态管理,Element Plus或Ant Design Vue作为UI框架。后端可…