日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > vue >内容正文

vue

浅聊vue双向绑定原理Object.defineProperty-/-Proxy

發(fā)布時(shí)間:2023/12/20 vue 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅聊vue双向绑定原理Object.defineProperty-/-Proxy 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
什么是雙向綁定呢?vue又是怎么做的我們接下來就聊一聊

什么是雙向綁定?

當(dāng)數(shù)據(jù)模型data變化時(shí),頁面視圖會得到響應(yīng)更新

vue又是怎么做的?

vue其實(shí)現(xiàn)原理是對data的getter/setter方法進(jìn)行攔截(Object.defineProperty或者Proxy),利用發(fā)布訂閱的設(shè)計(jì)模式,在getter方法中進(jìn)行訂閱,在setter方法中發(fā)布通知,讓所有訂閱者完成響應(yīng)。

說這些的時(shí)候我們在剛使用vue2.x的就會遇到過數(shù)據(jù)更新了啊,為何頁面不更新呢。這其實(shí)就是Object.defineProperty在作祟。

而在vue3還沒有發(fā)布時(shí),很火的一個(gè)話題就是Vue3將使用Proxy 取代Vue2 版本的Object.defineProperty。那么Proxy對比Object.defineProperty有什么優(yōu)勢。

Proxy對比Object.defineProperty

Proxy

  • Proxy可以直接監(jiān)聽對象而非屬性
  • Proxy可以直接監(jiān)聽數(shù)組的變化
  • Proxy有多達(dá)13種攔截方法,不限于apply、ownKeys、deleteProperty、has等等是Object.defineProperty不具備的
  • Proxy返回的是一個(gè)新對象,我們可以只操作新的對象達(dá)到目的,不需要像Object.defineProperty一樣遍歷每個(gè)屬性有一定的性能提升
  • Proxy作為新標(biāo)準(zhǔn)將受到瀏覽器廠商重點(diǎn)持續(xù)的性能優(yōu)化,也就是傳說中的新標(biāo)準(zhǔn)的性能紅利
  • Proxy直接實(shí)現(xiàn)對象屬性的新增/刪除

Object.defineProperty

  • Object.defineProperty只能劫持對象的屬性,需要遍歷對象的每一個(gè)屬性,如果屬性值也是對象,就需要遞歸進(jìn)行深度遍歷。

  • Object.defineProperty劫持的是對象的屬性,所以新增屬性時(shí),需要重新遍歷對象, 對其新增屬性再次使用Object.defineProperty進(jìn)行劫持。也就是Vue2.x中給數(shù)組和對象新增屬性時(shí),需要使用$set才能保證新增的屬性也是響應(yīng)式的, $set內(nèi)部也是通過調(diào)用Object.defineProperty去處理的。

冷知識

Object.defineProperty無法監(jiān)聽數(shù)組數(shù)據(jù)的變化,但是為什么數(shù)組在使用push pop等方法的時(shí)候可以觸發(fā)頁面更新呢,那是因?yàn)関ue內(nèi)部攔截了這些方法。比如數(shù)組在使用push pop等方法的時(shí)候?yàn)槭裁纯梢杂|發(fā)頁面更新呢,那是因?yàn)関ue內(nèi)部攔截了這些方法。

// 重寫push等方法,然后再把原型指回原方法var ARRAY_METHOD = [ 'push', 'pop', 'shift', 'unshift', 'reverse', 'sort', 'splice' ];var array_methods = Object.create(Array.prototype);ARRAY_METHOD.forEach(method => {array_methods[method] = function () {// 攔截方法return Array.prototype[method].apply(this, arguments);}});

回歸正題我們分別用代碼簡單的實(shí)現(xiàn)下Proxy對比Object.defineProperty如何實(shí)現(xiàn)綁定的

Object.defineProperty實(shí)現(xiàn)

// 這是將要被劫持的對象 const data = {name: '', }; // 遍歷對象,對其屬性值進(jìn)行劫持 Object.keys(data).forEach(function(key) {console.log('1')Object.defineProperty(data, key, {enumerable: true,configurable: true,get: function(newVal) {return val},set: function(newVal) {// 當(dāng)屬性值發(fā)生變化時(shí)我們可以進(jìn)行額外操作console.log(`大家好,我是${newVal}我被劫持了`);val = newVal;},}); }); data.name = '111';

Proxy實(shí)現(xiàn)

const target = {name: '控制' };const handler = {get: function(target, key) {console.log(`${key} 被讀取`);return target[key];},set: function(target, key, value) {console.log(`${key} 被設(shè)置為 ${value}`);target[key] = value;} };const testObj = new Proxy(target, handler);console.log(testObj.name); // name 被讀取 及輸出名字 控制 testObj.name = 1; // name 被設(shè)置為 1 輸出 1

Proxy參數(shù)介紹

1.get(target, propKey, receiver)

該方法的含義是:用于攔截某個(gè)屬性的讀取操作。它有三個(gè)參數(shù),如下解析:

  • target: 目標(biāo)對象。
  • propKey: 目標(biāo)對象的屬性。
  • receiver: (可選),該參數(shù)為上下文this對象

2.set(target, propKey, value, receiver)

該方法是用來攔截某個(gè)屬性的賦值操作,它可以接受四個(gè)參數(shù),參數(shù)解析分別如下:

  • target: 目標(biāo)對象。
  • propKey: 目標(biāo)對象的屬性名
  • value: 屬性值
  • receiver(可選): 一般情況下是Proxy實(shí)列

3.has(target, propKey)

該方法是判斷某個(gè)目標(biāo)對象是否有該屬性名。接收二個(gè)參數(shù),分別為目標(biāo)對象和屬性名。返回的是一個(gè)布爾型。

  • target: 目標(biāo)對象。
  • propKey: 目標(biāo)對象的屬性名

4.construct(target, args, newTarget)

該方法是用來攔截new命令的,它接收三個(gè)參數(shù),分別為 目標(biāo)對象,構(gòu)造函數(shù)的參數(shù)對象及創(chuàng)造實(shí)列的對象。
第三個(gè)參數(shù)是可選的。它的作用是攔截對象屬性。

  • target: 目標(biāo)對象。
  • args: 構(gòu)造函數(shù)的參數(shù)對象
  • newTarget:創(chuàng)造實(shí)列的對象

5.apply(target, object, args)

該方法是攔截函數(shù)的調(diào)用的。該方法接收三個(gè)參數(shù),分別是目標(biāo)對象。目標(biāo)對象上下文this對象 和 目標(biāo)對象的數(shù)組;它和 Reflect.apply參數(shù)是一樣的
第三個(gè)參數(shù)是可選的。它的作用是攔截對象屬性。

  • target: 目標(biāo)對象。
  • object: 目標(biāo)對象上下文this對象
  • args:目標(biāo)對象的數(shù)組

寫在最后的話大家不要忘記,點(diǎn)贊,評論,收藏

總結(jié)

以上是生活随笔為你收集整理的浅聊vue双向绑定原理Object.defineProperty-/-Proxy的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。