vue3数据劫持proxy

这篇具有很好参考价值的文章主要介绍了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);        // 0
    
proxyObj.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 true
   notifyRender() // 通知订阅者更新
   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解决方案。文章来源地址https://www.toymoban.com/news/detail-810634.html

到了这里,关于vue3数据劫持proxy的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端技术Html,Css,JavaScript,Vue3

    1.基本标签 2.文本格式化 3.链接 4.图片 5.无序列表 6.有序列表 7.表格 8.表单 1.选择器 2.文本和字体 3.链接 4.隐藏 5.定位position 6.浮动 7.对齐 8.图像 1.输出 2.函数 3.常用事件 4.DOM 5.改变Html 6.DOM 元素 (节点) 尾部创建新的 HTML 元素 (节点) - appendChild() 头部创建新的 HTML 元素 (节点)

    2024年02月13日
    浏览(45)
  • 前端2023最全面试题(javaScript、typeScript、vue2、vue3、html、css、uniapp、webpack、vite、react)

    答案:JavaScript中的闭包是一种函数,它有权访问其词法环境的变量和其它函数。这意味着,即使其包含它的函数已经执行完毕,其词法环境仍然存在,因此可以访问其作用域内的变量。 答案:回调函数是在某个特定事件之后执行的函数。在JavaScript中,通常使用回调函数来处

    2024年02月06日
    浏览(56)
  • 服务端使用ASP.NET Core SignalR与Vue3(TypeScript与JavaScript)前端建立通信(以进度条为例)

    1. ASP.NET Core           ASP.NET Core 是一个跨平台、高性能及开源的框架,用于生成基于云且连接互联网的新式应用程式。 官方文档:ASP.NET documentation | Microsoft Learn  2.  ASP.NET Core SignalR         ASP.NET Core SignalR 是开源库,用于服务端与客户端建立实时通信,可以自动管理连接

    2024年02月06日
    浏览(41)
  • 【vue3源码系列#01】vue3响应式原理(Proxy)

    专栏分享:vue2源码专栏,vue3源码专栏,vue router源码专栏,玩具项目专栏,硬核💪推荐🙌 欢迎各位ITer关注点赞收藏🌸🌸🌸 在学习 Vue3 是如何进行对象的响应式代理之前,我想我们应该先去了解下 ES6 新增的API Proxy 与 Reflect ,可参考【Vue3响应式入门#02】Proxy and Reflect 。之

    2024年02月05日
    浏览(42)
  • VUE3浅析---pinia和proxy

    1、概念: Pinia 是 Vue3 的存储库,代替 Vuex 成为VUE3的状态管理工具。相比于 Vuex 它有以下优势: - 不存在mutations,存储数据的方式更加简化。 - 在组件上可以直接做存储库中的数据的修改,并且都是响应式的。 - 贴合ts。 2、安装并使用 2.1、安装 2.2、使用:在src目录下定义

    2024年02月11日
    浏览(30)
  • vue3.0 proxy设置代理不成功

    首先在项目中创建vue.config.js 注意在ts环境下仍为js结尾 项目配置详情如下: 结果运行依然报错 最后还是出现在axios的默认基本路径的配置和代理发生了冲突,代理本身是将请求基本路径代理到目标基本路径 比如: 项目基本路径是http:localhost:8080 axios 基本路径却设置为http:loc

    2024年02月12日
    浏览(30)
  • 【源码系列#01】vue3响应式原理(Proxy)

    专栏分享:vue2源码专栏,vue3源码专栏,vue router源码专栏,玩具项目专栏,硬核💪推荐🙌 欢迎各位ITer关注点赞收藏🌸🌸🌸 在学习 Vue3 是如何进行对象的响应式代理之前,我想我们应该先去了解下 ES6 新增的API Proxy 与 Reflect ,可参考【Vue3响应式入门#02】Proxy and Reflect 。之

    2024年02月05日
    浏览(44)
  • 【Vue3响应式原理#02】Proxy and Reflect

    专栏分享:vue2源码专栏,vue3源码专栏,vue router源码专栏,玩具项目专栏,硬核💪推荐🙌 欢迎各位ITer关注点赞收藏🌸🌸🌸 以下是柏成根据Vue3官方课程整理的响应式书面文档 - 第二节,课程链接在此:Proxy and Reflect - Vue 3 Reactivity | Vue Mastery 本篇文章将解决 上一篇文章 结

    2024年02月05日
    浏览(56)
  • vue3配置代理--[vite] http proxy error

    跨域请求数据, 浏览器 同源策略的保护机制, 通过 proxy 实现跨域请求数据; 如果直接 postman 请求是不会报错的, vue3 报错是因为经过浏览器了, 数据其实返回了, 但是别浏览器的同源策略屏蔽了。 本地调试, 后端使用** http://localhost:8081 作为接口地址, 报错 [vite] http proxy error ** 可

    2024年02月08日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包