Vue2和Vue3的双向数据绑定原理
创始人
2024-05-02 16:59:13
0

目录

  • 前言:
  • vue2.x 是如何实现响应式系统的:
  • defineProperty 的痛点:
  • Object.defineProperty 代码的使用
  • Proxy 方法的理解
  • Proxy 代码的使用:
  • 总结:

前言:

今天小编给大家讲解一下,Vue2和Vue3的双向数据绑定原理。

我正在参加 2022年「博客之星」年度总评选,请大家帮我支持一下,给我一个五星。
|
点击前往我的评选页面:
|
在这里插入图片描述
大家只要按图给我五星即可,谢谢大家的帮助。

vue2.x 是如何实现响应式系统的:

当你把一个普通的 js 对象传入 vue 实例作为 data 选项,vue 将遍历此对象的所有prototype(属性),并使用 object.defineProperty(),将这些 prototype(属性),全部转换为 getter / setter,在 getter 中收集数据依赖,在 setter 中监听数据变化,一旦数据发生改变,在通知订阅者。

每个组件实例,都对应一个 watcher 实例,它会在组件渲染的过程把 “接触” 过的数据 prototype(属性)记录为依赖,之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染;


defineProperty 的痛点:

  1. 它无法发现对象新增和被删除的属性,当你给一个对象添加一个新的属性,这个新增的属性没有添加到 vue 的数据更新侦查机制里;

Vue.set() 可以让 vue 知道你新增了一个属性,其实 Vue.set 可以让 Vue 知道新增了一个属性。其实 set() 内部也是通过调用 defineProperty() 来实现;

  1. 当你利用索引直接设置一个数组(new Array(4))或者修改数组的长度时,Vue 不能检测到数组的变动;
  2. 当对象嵌套的层数特别深(多层嵌套)的时候,递归遍历带来的性能开销就会比较大;

Object.defineProperty 代码的使用

mounted() {// 先定义好一套规则class Observer {constructor(data) {for (let key of Object.keys(data)) {if (typeof data[key] === "object") {data[key] = new Observer(data[key]);}Object.defineProperty(this, key, {enumerable: true,configurable: true,get() {console.log("You visited" + key);return data[key];},set(NewValue) {console.log("You set" + key);console.log("New Value" + NewValue);if (NewValue === data[key]) {return;}data[key] = NewValue;},});}}}let obj = {name: "app",age: 18,a: {b: 1,c: {d: 1,},},};let app = new Observer(obj);console.log(app);app.age = 20;app.newProperty = "new attrs";console.log(app);},

结果:
在这里插入图片描述


Proxy 方法的理解

Proxy 在 vue3.0 中上位

可以解决 defineProperty 的痛点,因为本质的原因在于 Proxy 是内置了拦截器对象。所有的外部访问都得先经过这一层拦截,不管是先前定义好的,还是新增的属性,又或者是深层的嵌套属性,访问时都会被拦截;

Reflect.set()方法用于设置对象属性的值,1:目标对象:2:改变参数的名称:3:改变参数的值:4:值是this如果遇到设置器,将提供给目标调用。
此方法返回一个布尔值,该值指示该属性是否已成功设置。


Proxy 代码的使用:

mounted() {const obj = {name: "app",age: 19,a: {b: 1,c: 2,},};const p = new Proxy(obj, {get(target, propKey, receiver) {console.log("Your visited:" + propKey);// Reflect.set()方法用于设置对象属性的值:1:目标对象:2:改变参数的名称:3:改变参数的值// 此方法返回一个布尔值,该值指示该属性是否已成功设置。return Reflect.set(target, propKey, receiver);},set(target, propKey, value, receiver) {console.log("You set:" + propKey);console.log("New value:" + value);// Reflect.set()方法用于设置对象属性的值,1:目标对象:2:改变参数的名称:3:改变参数的值:4:值是this如果遇到设置器,将提供给目标调用。// 此方法返回一个布尔值,该值指示该属性是否已成功设置。return Reflect.set(target, propKey, value, receiver);},});p.age = "20";console.log(p);p.newProperty = "New attribute";console.log(p);},

结果:
在这里插入图片描述


总结:

  1. proxy 是用来操作对象并且扩展对象能到,而 Object.defineProperty() 只是单纯的操作对象的属性;
  2. Vue2.X 是用 Object.defineProperty() 实现数据响应的,但是受限于 defineProperty() 的实现,必须递归遍历至对象的最底层;
  3. vue3.0 用 Proxy 来拦截对象,不管对目标执行任何操作,都会先通过 Proxy 的处理逻辑;
  4. 除了 Vue3.0,还有其他的库也在使用 Proxy。

最后还请大家帮我点击一下,谢谢大家的帮助

我正在参加 2022年「博客之星」年度总评选,请大家帮我支持一下,给我一个五星。
|
点击前往我的评选页面:
|
在这里插入图片描述
大家只要按图给我五星即可,谢谢大家的帮助。


以上就是 Vue2和Vue3的双向数据绑定原理,不懂得也可以在评论区里问我或私聊我询问,以后会持续发布一些新的功能,敬请关注。
我的其他文章:https://blog.csdn.net/weixin_62897746?type=blog

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...