当前位置:首页 > 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)实现监听。

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) {
    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 CLI 创建项目 安装 Vue CLI 并初始化项目: npm install -g @vue/cli vue create user-info-tabl…

vue实现数据

vue实现数据

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

vue 实现路径

vue 实现路径

在 Vue 中实现路径管理通常涉及路由配置、动态路由、嵌套路由等场景,以下是具体实现方法: 基础路由配置 安装 Vue Router 并创建路由实例: npm install vue-router…

vue实现侧导航

vue实现侧导航

Vue 实现侧边导航 使用 Vue 实现侧边导航可以通过多种方式完成,以下是一种常见的实现方法,结合 Vue Router 和动态组件。 基础结构 创建侧边导航栏的基本结构,通常使用 <ul&…

vue路由实现滑动

vue路由实现滑动

实现 Vue 路由滑动效果的方法 使用 Vue Router 结合 CSS 过渡动画 在 Vue Router 的路由视图组件 <router-view> 上添加过渡效果,结合 CSS 实…

vue实现切换城市

vue实现切换城市

实现思路 通过Vue的状态管理(如Vuex或Pinia)存储当前城市数据,结合下拉菜单或选项卡组件实现城市切换功能。切换时更新状态并触发相关数据重新加载。 核心代码实现 1. 状态管理(以Pinia…