当前位置: 首页 > article >正文

Vue响应式原理实现总结(数据劫持Object.defineProperty/Proxy+发布订阅者设计模式)

Vue的响应式主要分为数据劫持和发布订阅模式。Vue2用的是Object.defineProperty,而Vue3改用Proxy。数据劫持就是在访问或修改对象属性时进行拦截,然后触发相应的更新。发布订阅模式则是用来收集依赖(比如视图更新函数),当数据变化时通知这些依赖执行。
总结一下,关键点包括:

  1. 使用Object.defineProperty或Proxy进行数据劫持
  2. 在getter中收集依赖(Watcher到Dep)
  3. 在setter中触发Dep的通知,执行所有Watcher的更新
  4. 发布订阅模式通过Dep和Watcher实现依赖管理

在这里插入图片描述
在这里插入图片描述

相关知识

数据劫持实现

以下是关于 Object.defineProperty()Proxy 的详细介绍和对比:


一、Object.defineProperty()

1. 核心功能

  • 定义:JavaScript 原生方法,用于直接在对象上定义新属性,或修改现有属性。
  • 核心能力:通过 gettersetter 拦截属性的读写操作
  • 兼容性:ES5+,支持所有现代浏览器及 IE9+。

2. 基本语法

Object.defineProperty(obj, prop, {
   
  get() {
    /* 读取属性时触发 */ },
  set(newVal) {
    /* 修改属性时触发 */ },
  enumerable: true, // 可枚举
  configurable: true // 可配置(如删除)
});

3. 典型用途

const data = {
    count: 0 };

// 劫持属性
Object.defineProperty(data, "count", {
   
  get() {
   
    console.log("读取 count");
    return this._count; // 使用临时变量存储值
  },
  set(newVal) {
   
    console.log("修改 count");
    this._count = newVal;
  }
});

data.count = 1; // 输出 "修改 count"
console.log(data.count); // 输出 "读取 count" → 1

4. 局限性

场景 问题描述
新增属性 无法劫持未预先定义的属性
数组索引修改 直接通过索引修改元素无法触发监听
数组方法(push等) 需重写数组方法才能劫持
深层对象 需递归遍历所有属性,性能较差

二、Proxy

1. 核心功能

  • 定义:ES6 新增的元编程特性,用于创建一个对象的代理,拦截并自定义对象的基本操作。
  • 核心能力:拦截 13 种对象操作(如读写属性、删除属性、方法调用等)。
  • 兼容性:ES6+,不支持 IE11 及更低版本。

2. 基本语法

const proxy = new Proxy(target, {
   
  get(target, prop) {
    /* 拦截属性读取 */ },
  set(target, prop, value) {
    /* 拦截属性修改 */ },
  // 其他拦截器:deleteProperty、has、ownKeys 等
});

3. 典型用途

const data = {
    count: 0 };

const proxy = new Proxy(data, {
   
  get(target, prop) {
   
    console.log(`读取 ${
     prop}`);
    return Reflect.get(target, prop);
  },
  set(target, prop, value) {
   
    console.log(`修改 ${
     prop}${
     value}`);
    return Reflect.set(target, prop, value);
  }
});

proxy.co

http://www.kler.cn/a/547265.html

相关文章:

  • 【C++】32.C++11​(4)
  • 第二月:学习 NumPy、Pandas 和 Matplotlib 是数据分析和科学计算的基础
  • 图论- Dijkstra算法
  • 【Linux】进程间通信——管道通信
  • 蓝桥杯篇---温度传感器 DS18B20
  • Redis进阶使用
  • nsc account 及user管理
  • 香港VPS服务器如何排查和修复 MySQL 数据库连接失败的问题
  • Rook-ceph(1.92最新版)
  • LeetCode 热题 100_括号生成(59_22_中等_C++)(递归(回溯))
  • 文本表示方法
  • 变相提高大模型上下文长度-RAG文档压缩-2.带早停机制的map-refine
  • CAS单点登录(第7版)9.属性
  • CAS比较并交换
  • 《Python全栈开发:构建高并发物联网数据中台实战》
  • 使用 playwright 自定义 js 下载的路径和文件名
  • 智能编程助手功能革新与价值重塑之:GitHub Copilot
  • Word正文中每两个字符之间插入一个英文半角空格
  • Myplater项目
  • 【Linux】详谈 进程控制