写在前面

如果你对Vue发布订阅的响应式实现有一定的了解,那么你一定知道defineProperty。

Object.defineProperty(obj, prop, descriptor)

Vue2.x中的响应式实现正是基于defineProperty中的descriptor,通过属性的getter、setter监听来实现的。

同时你应该知道的是,我们在Vue中使用下标的方式直接修改属性的值或者添加一个预先不存在的对象属性是无法做到setter监听的,这是defineProperty的局限性。

而我们在Vue中使用的push、pop、shift、unshift、splice等一系列修改原数组的方法,其实不是原生的数组方法,都是被Vue修改过的,其中加入了响应代码。

有消息称Vue3.0的响应式将会使用Proxy来实现,这一举动无疑优化了Vue的响应能力,但是也决定了Vue将会彻底抛弃IE阵营,我们是否应该默(qing)哀(zhu) 一分钟。

defineProperty中的getter、setter

defineProperty的局限性的最大原因是它只能针对单例属性做监听,Vue2.x中对data中的属性做了遍历 + 递归,为每个属性设置了getter、setter。

这也就是为什么Vue只能对data中预定义过的属性做出响应的原因。

defineProperty的用法

    var val = 1var obj = Object.defineProperty({}, 'sum', {enumerable: true,configurable: true,get() {return val},set(newValue) {val += newValue}})
复制代码

测试代码:

我们也可以这样写:

    var val = 1var obj = {get ['sum']() {return val},set ['sum'](newValue) {val += newValue}}
复制代码

这段代码和上面代码结果是一样的。

这里的'sum'就是被监听的属性名,也就是我们需要监听的“一个”属性。

正是因为使用defineProperty每次只能绑定一个属性监听,所以Vue在遍历 + 递归时要有更大的性能消耗和更多的代码。

Proxy中的getter、setter

Vue3.0终于要使用Proxy,就像上文说的一样,首先应该对IE表示沉(xi)痛(wen)哀(le)悼(jian)。

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。

也就是说,Proxy的监听是针对一个对象的,那么对这个对象的所有操作会进入监听操作,这就完全可以代理所有属性了。

更多Proxy用法可以看 阮一峰大神的ES6入门-Proxy,本文只讲解getter、setter实现。

使用Proxy监听

    var data = {sum: 0}var proxy = new Proxy(data, {get(target, property) {return target[property]},set(target, property, value) {target[property] += value}})
复制代码

Proxy测试

当data为数组时:

Proxy中getter、setter说明

get接收三个参数: get(target, propKey, receiver)

target是被监听对象,在示例代码中表示的是data propKey是属性名,即当前需要获取的属性名 receiver是监听对象,即Proxy实例,在示例代码中表示的是proxy

set接收四个参数: get(target, propKey, value, receiver)

targetpropKeyreceiver三个参数和get中一样 value表示被修改的值,即测试代码中的1

很明显的是,我们使用Proxy时并不需要关心某一个具体的属性,并且Proxy实例上的修改不会影响到被监听对象target中的值(前提是你不主动修改target)。

Proxy中getter、setter的局限性

让我们看看以下代码:

    var data = {a: { b: 0 }}var proxy = new Proxy(data, {get(target, property) {console.log(`path: ${property}`)return target[property]},set(target, property, value) {console.log(`path: ${property}`)target[property] += value}})
复制代码

打印结果:

很明显的是,proxy代理getter、setter只会关注浅层数据,而不会返回深层路径。

如果path在这里能够返回a.b那么将会带来一个很好的收益,不过既然Proxy规范没有实现那么我们也是无计可施。

而且从理解上来说修改proxy.a.b返回的修改对象名是a貌似也是正确的,现在我们需要做的是记住这一结论就好。

结语

Proxy和defineProperty中getter、setter的用法就说到这里。

可以预见的是,Vue3.0中使用Proxy代理将会带来很大的性能提升和更优的代码。

但是就像react中约定的一样,对于引用类型值的响应式的支持可能会变得比以前更不友好(需要开发者实现浅拷贝赋值)。

不过如果尤大依旧选择使用递归的方式来解决对象类型数据的响应式,我个人看来是有些得不偿失的。

从我自己的意愿来看,我更希望是借助于immutable,而不是走递归遍历的老路。

相信尤大一定会有自己的考量,最终的结果肯定是令大部分人满意的方案。

同时Vue3支持typescript的方向更是令我激动不已,作为尤大的粉丝,我们好好期待就是了。

vue3.0为什么要用Proxy替代defineProperty相关推荐

  1. 我来说说 Vue面试知识点 和 Vue3.0

    昨天文章刚说了React的重要性和为何流行,今天北妈带你回归Vue,云里雾里.懵不懵逼都在你自己,反正无论如何,这一年我会疯狂的让大家学习,催促自己和你们一起学习,并且一起参与其中. 入正题 一 昨天 ...

  2. 学习Vue3.0笔记

    Vue3.0快速上手 @[TOC](Vue3.0快速上手) Vue3简介 Vue3.0相对于Vue2多了些什么? 1.性能的提升 2.源码改变 3.拥抱TS 4.新特性(重点) 常用的组合式API V ...

  3. Vue3.0之双向绑定原理——Proxy

    了解代理模式 一个例子 作为一个单身钢铁直男程序员,小王最近逐渐喜欢上了前端小妹,不过呢,他又和前台小妹不熟,所以决定委托与前端小妹比较熟的UI小姐姐帮忙给自己搭桥引线.小王于是请UI小姐姐吃了一顿大 ...

  4. 学习Vue3.0,先来了解一下Proxy

    产品经理身旁过,需求变更逃不过. 测试姐姐眯眼笑,今晚bug必然多. 据悉Vue3.0的正式版将要在本月(8月)发布,从发布到正式投入到正式项目中,还需要一定的过渡期,但我们不能一直等到Vue3正式投 ...

  5. (六)Vue3.0预学习

    Vue3.0预学习 Vue3要来了Vue2就要过时了吗 Vue3 Vue2.x马上就要过时了吗 Vue3升级内容 Proxy实现响应式 Object.defineProperty的缺点 Proxy实现 ...

  6. Vue最全知识点,面试必备(基础到进阶,覆盖vue3.0,持续更新整理,欢迎补充讨论)

    声明:本篇文章纯属笔记性文章,非整体原创,是对vue知识的整理,对自己有很大帮助才分享出来,参考文章传送:1.童欧巴对vue知识的整理 2.我是你的超级英雄对vue知识的整理 3.vue官网 基础篇 ...

  7. vue3.0初体验(例子解读reactive响应式)

    目录 准备 vue3 reactive原理例子重点讲解 vue3 reactive原理例子完整代码 准备: 下载vue-next 安装依赖 npm install 核心部分package,里面的vue ...

  8. 覆盖vue3.0的最全Vue知识点

    声明:本篇文章纯属笔记性文章,非整体原创,是对vue知识的整理,对自己有很大帮助才分享出来,参考文章传送:1.童欧巴对vue知识的整理 2.我是你的超级英雄对vue知识的整理 3.vue官网 基 础 ...

  9. Vue最全知识点「基础到进阶,覆盖vue3.0,建议收藏」

    作者: 阿李卑斯 https://juejin.im/post/5ec358126fb9a0432a3c49e6 文末送<Vue.js从入门到项目实战>书籍 希望你坚持看完并带走彩蛋 声明 ...

最新文章

  1. Windows10下安装配置 perl 环境
  2. 【原创 HadoopSpark 动手实践 1】Hadoop2.7.3 安装部署实践
  3. 云计算还是python_云计算 与python
  4. ext2.2打造全新功能grid系列--仅仅动态生成GridPanel
  5. cs224n第一讲深度自然语言处理
  6. COM编程入门---转发
  7. python医学图像读取_对python读取CT医学图像的实例详解
  8. ImportError: cannot import name ‘Optional‘
  9. vi/vim 按键说明
  10. 分享2个Python处理Excel的脚本
  11. RT-Thread : IEEE1588/PTP 协议的实现
  12. 怎么恢复优盘里隐藏的数据 u盘隐藏数据恢复教程
  13. python函数里调用外部变量
  14. async、await其实是generator和promise的语法糖
  15. Centos7开小鸡(centos7安装KVM+kimchi+wok开小鸡)第一篇安装kimchi wok
  16. Hololens开发学习笔记-4
  17. Nginx反向代理解决跨域问题(个人学习总结)
  18. matlab .m 返回值,MATLAB一个M文件的function返回值怎么在另一个M文件中的函数调用这个返回值?...
  19. 计算机组成原理简答题
  20. html静态页面作业——海贼王中乔巴漫画(5页) 学生动漫网页设计模板下载 海贼王大学生HTML网页制作作品 简单漫画网页设计成品

热门文章

  1. 【渝粤题库】陕西师范大学164208 网络营销理论与实务 作业(专升本)
  2. 记一次·ulimit: open files: cannot modify limit:不允许操作
  3. java 数字转化为汉字_工具类_java 数字转化为汉字大写
  4. 拒绝校园欺凌丨盐城北大青鸟机电基地开展法制宣传讲座
  5. python3下载mapbox矢量切片
  6. 为什么叫vanilla neural network?
  7. 使用dba_waiters检查锁等待
  8. HMM(隐马尔可夫)
  9. 下载Linux ISO镜像的方法 (带你快速了解)
  10. HDU1814和平委员会