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

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

相关文章:

  • STM32 如何使用DMA和获取ADC
  • 5分钟了解! 探索 AnythingLLM,借助开源 AI 打造私有化智能知识库,熟悉向量数据库
  • 【Unity3D优化】AssetBundle的压缩格式优化
  • Rust 组织管理
  • rk3588部署yolov6
  • Docker配置镜像加速-解决黑马商城部署Mysql失败问题
  • 【算法】递归入门
  • 详解 JavaScript 中 fetch 方法
  • Linux的IO编程基础:从入门到实践
  • 《Spring实战》(第6版)第2章 开发Web应用
  • 【xdoj-离散线上练习】T234(C++)
  • 初始c语言(指针和结构体)
  • 数据结构——栈
  • Linux 更改 SSH 默认端口以提升服务器安全
  • 数据结构与算法之排序算法-选择排序
  • APP端弱网模拟与网络测试:如何确保应用在各种网络环境下稳定运行
  • 【动态规划】斐波那契数列模型
  • OpenCV 模板匹配
  • 算法-链表篇03-反转链表
  • EasyX学习笔记1:线条
  • 15年全免费,内蒙古准格尔旗实现幼儿园到高中0学费
  • 芬兰直升机相撞坠毁事故中五名人员全部遇难
  • 雷军内部演讲回应质疑:在不服输、打不倒方面,没人比我们更有耐心
  • 俄代表团:16日上午将继续“等候乌代表团”
  • 阿里上季度营收增7%:淘天营收创新高,AI产品营收连续七个季度三位数增长
  • 湖北宜化拟斥资超32亿加价回购“弃子”,布局上游煤炭业务