vue3数据劫持proxy

一、vue2响应式设计

  vue2利用Object.defineProperty来劫持data数据的getter和setter操作,遇到数组和对象必须循环遍历所有的域值才能劫持每一个属性 。

Object.keys(data).forEach((prop) => {const dep = new Dep();Object.defineProperty(data, prop, {get () {dep.depend();return Reflect.get(data, prop);},set (newVal) {Reflect.set(data, prop, newVal);dep.notify();}});
});

缺点:1、 无法检测到对象属性的新增或删除 ,需要使用 set 等其他方法。

二、Proxy响应式

  vue2响应式不能监听数组,局限于数组的push/pop/shift/unshift/splice/sort/reverse七个方法,vue2会封装这七种方法,使其可以被监听变化。

  而更快的es6中的原生proxy就能解决这些问题,为什么vue3才使用 Proxy ,原因还是浏览器兼容所限。至今IE仍不支持Proxy,所以vue3还是为原始浏览器保留了Object.defineProperty的实现。

  MDN :Proxy`对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)

  可以理解为在目标对象之前做一层拦截,外部所有的访问都必须通过这层拦截,通过这层拦截可以做很多事情,比如对数据进行过滤、修改或者收集信息之类。

let obj = {a : 1
}
let proxyObj = new Proxy(obj,{get : function (target,prop) {return prop in target ? target[prop] : 0},set : function (target,prop,value) {target[prop] = 888;}
})console.log(proxyObj.a);        // 1
console.log(proxyObj.b);        // 0proxyObj.a = 666;
console.log(proxyObj.a)         // 888

  Proxy构造函数的第一个参数是原始数据data;第二个参数是一个叫handler的处理器对象。Handler是一系列的代理方法集合,它的作用是拦截所有发生在data数据上的操作。这里的get()和set()是最常用的两个方法,分别代理访问和赋值两个操作。

const list = [1, 2];const observer = new Proxy(list, {set: function(obj, prop, value, receiver) {console.log(`prop: ${prop} is changed!`);return Reflect.set(...arguments);},
});observer.push(3);
observer[3] = 4;

  Proxy不需要各种hack技术就可以无压力监听数组变化;甚至有比hack更强大的功能——自动检测length。除此之外,Proxy还有多达13种拦截方式,包括construct、deleteProperty、apply等等操作;而且性能也远优于Object.defineProperty。

let handler = {
get(target, key){if (target[key] === 'object' && target[key]!== null) {// 嵌套子对象也需要进行数据代理return new Proxy(target[key], hanlder)}collectDeps() // 收集依赖return Reflect.get(target, key)
},
set(target, key, value) {if (key === 'length') return truenotifyRender() // 通知订阅者更新return Reflect.set(target, key, value);
}
}
let proxy = new Proxy(data, handler);
proxy.age = 18 // 支持新增属性
let proxy1 = new Proxy({arr: []}, handler);
proxy1.arr[0] = 'proxy' // 支持数组内容变化

  Proxy代理目标对象,每个拦截方式与ES6提供的另一个apiReflect的13种静态方法一一对应。二者一般是配合使用的,在修改proxy代理对象时,一般也需要同步到代理的目标对象上,这个同步就是用Reflect对应方法来完成的。例如上面的Reflect.set(target, key, value)同步目标对象属性的修改。

三、 Proxy的13种拦截方式

trap描述
handler.get获取对象的属性时拦截
handler.set设置对象的属性时拦截
handler.has拦截propName in proxy的操作,返回boolean
handler.apply拦截proxy实例作为函数调用的操作,proxy(args)、proxy.call(…)、proxy.apply(…)
handler.construct拦截proxy作为构造函数调用的操作
handler.ownKeys拦截获取proxy实例属性的操作,包括Object.getOwnPropertyNames、Object.getOwnPropertySymbols、Object.keys、for…in
handler.deleteProperty拦截delete proxy[propName]操作
handler.defineProperty拦截Objecet.defineProperty
handler.isExtensible拦截Object.isExtensible操作
handler.preventExtensions拦截Object.preventExtensions操作
handler.getPrototypeOf拦截Object.getPrototypeOf操作
handler.setPrototypeOf拦截Object.setPrototypeOf操作
handler.getOwnPropertyDescriptor拦截Object.getOwnPropertyDescriptor操作

四、Proxy的应用场景

  1. Vue3的数据响应
  2. 获取属性对应的值,无该属性或者属性为空返回默认值
  3. 实现数组负数索引的访问
  4. 缓存
  5. 隐藏属性
  6. 只读视图

五、Proxy的缺点

  大部分浏览器支持Proxy特性,但是一些浏览器或者其低版本不支持Proxy,其中IE、QQ浏览器、百度浏览器等完全不支持,因此Proxy有兼容性问题。也不能像ES6其他特性那样有对应的polyfill解决方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/638483.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

urllib模块使用

urllib.request.urlopen(url, dataNone, [timeout, ]*, cafileNone, capathNone, cadefaultFalse, contextNone) import urllib.requesturl http://httpbin.org/ip response urllib.request.urlopen(url) html response.read() # 返回bytes类型数据 print(html)url http:…

一个非常流行的R语言调色板:RColorBrewer

R 语言有许多非常优秀的调色板,本文就介绍一个非常流行的,我也经常在用的调色板 R 包:RColorBrewer。 安装 install.packages("RColorBrewer") 加载 library(RColorBrewer) library(knitr) 初探 ?RColorBrewer 在帮助页面可以看到…

Oracle数据库协议适配器错误解决方法

🕺作者: 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux 😘欢迎关注:👍点赞🙌收藏✍️留言 🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要&…

Python实现单因素方差分析

Python实现单因素方差分析 1.背景 正念越来越受到人们关注,正念是一种有意的、不加评判的对当下的注意觉察。可以通过可以通过观呼吸、身体扫描、正念饮食等多种方式培养。 为了验证正念对记忆力的影响,选取三组被试分别进行正念训练,运动训…

使用STM32的UART实现蓝牙通信

✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进 代码获取、问题探讨及文章转载可私信。 ☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。 🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!&#x1f447…

外部配置文件和Class打包到jar 然后重新启动java -jar

我这边以demo.jar和application-dev.properties配置文件为例 一.将Test1.class和Test2.class替换到jar内部 步骤1:解压原始demo.jar 将两个class文件拷贝到jar目录下后cd到文件目录执行: jar xf demo.jar BOOT-INF/classes/com/test/ jar xf demo.jar…

解密.dataru被困的数据:如何应对.dataru勒索病毒威胁

导言: 在数字时代,勒索病毒如.dataru正在不断演变,威胁着用户的数据安全。本文91数据恢复将深入介绍.dataru勒索病毒的特点、被加密数据的恢复方法,以及预防措施,帮助您更好地了解并对抗这一数字威胁。当面对被勒索病…

基于SpringBoot的在线问卷调查管理系统

基于SpringBoot的在线问卷调查管理系统的设计与实现~ 开发语言:Java数据库:MySQL技术:SpringBootMyBatis工具:IDEA/Ecilpse、Navicat、Maven 系统展示 前台主页 问卷列表 问卷详情 管理员界面 摘要 基于Spring Boot的在线问卷调…

JVM篇--垃圾回收器高频面试题

1 你知道哪几种垃圾收集器,各自的优缺点是啥,重点讲下cms和G1,包括原理,流程,优缺点? 1)首先简单介绍下 有以下这些垃圾回收器 Serial收集器: 单线程的收集器,收集垃圾时…

云贝教育 |【OceanBase】OBCA认证考试预约流程

一、OBCA账号登录/注册,链接 https://www.oceanbase.com/ob/login/mobile?gotohttps%3A%2F%2Fwww.oceanbase.com%2Ftraining%2Fdetail%3Flevel%3DOBCA 注册完之后,请点击右上“登录”进行实名认证 OBCA考试报名链接:https://www.oceanbase.…

SQLite的临时视图和“一般”视图的区别

在SQLite中,临时视图和永久视图是两种不同的对象,它们之间有几个关键的区别: 作用域(Scope): 临时视图(Temporary View):仅在创建它的数据库连接会话中可见和可用。当创…

stm32cubemx下载以及安装【最新版本傻瓜式教程】

一、官网 https://www.st.com/zh/development-tools/stm32cubemx.html 二、下载【废话不多说,按照图示所圈进行】 没有登录账号的建议先注册登录再进行下载,这样省去后面认证的麻烦。 选择自己电脑对应环境的版本,我的是windows11&#xf…

MSE Nacos:解决敏感配置的安全隐患

作者:察溯 前言 Nacos 简介 Nacos [ 1] 是一个更易于构建云原生应用的配置管理和服务管理平台。Nacos 的配置中心具有众多优势:动态实时更新配置、支持水平扩展的高可用系统架构、API 简单易上手、开源免费、多语言支持、集成度高等。基于以上特点&am…

JavaScript 中JSON 字符串和对象之间的转换。

JSON.stringify() 方法(对象转换为 JSON 字符串) 用于将 JavaScript 对象转换为 JSON 字符串。 它接受一个 JavaScript 对象作为参数,并返回对应的 JSON 字符串表示。例如: const obj { name: John, age: 25 }; const jsonStr…

0基础实战langchain系列讲义【2】LangChain 的数据连接

文章目录 前言1、数据连接定义?2、数据的加载、拆分过程2.1 TextLoader 加载文档2.2 拆分文档2.2.1 字符拆分2.2.2 拆分代码2.2.3 Markdown文档拆分2.2.4 按字符递归拆分2.2.5 按token拆分 3 文本向量化和向量数据库存储查询3.1 文本向量化分块3.2 向量化存储、检索…

Html+Css+JavaScript实现完整的轮播图功能

概要 这个案例具备常见轮播图完整的功能,大家可以根据自己的需求去修改; 代码可以直接复制运行,需要安装sass 主要功能: (1)鼠标移入轮播图,左右两边的按钮出现,离开则隐藏按钮&a…

proteus8.15安装教程

proteus8.15安装教程 1.管理员运行 2.一直NEXT到这一步,需要注意,一定要选这一个 3.选中后出现 4.一直下一步到更新 这边结束后准备激活: 1.安装激活插件,先关闭防火墙 2.下一步 3.最后,将数据库放在根目录下 …

从零开始配置pwn环境:sublime配置并解决pwn脚本报错问题

1.sublime安装 Download - Sublime Text ──(holyeyes㉿kali2023)-[~] └─$ sudo dpkg -i sublime-text_build-4169_amd64.deb [sudo] password for holyeyes: Selecting previously unselected package sublime-text. (Reading database ... 409163 files and directori…

LeetCode——二叉树

二叉树 思路【labuladong】 1)是否可以通过遍历一遍二叉树得到答案?如果可以,用一个traverse函数配合外部变量来实现——回溯 2)是否可以定义一个递归函数,通过子问题的答案推导出原问题的答案?如果可以…

Halcon模板图像gen_contour_region_xld/find_shape_model

Halcon模板图像 文章目录 Halcon模板图像1. 从参考图像的特定区域中创建模板2. 使用XLD轮廓创建模板 本文将讲述如何创建合适的模板。可以从参考图像的特定区域中创建,也可以使用XLD轮廓创建合适的模板。接下来将分别介绍这两种方法。 1. 从参考图像的特定区域中创建…