国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

3分鐘了解vue數據劫持的原理實現

2024-05-06 15:39:56
字體:
來源:轉載
供稿:網友

目的: 了解Object.defineProperty如何實現數據劫持

大致原理是這樣的:

    定義一個監聽函數,對對象的每一個屬性進行監聽 通過Object.defineProperty對監聽的每一個屬性設置get 和 set 方法。 對對象實行監聽 對對象內嵌對象進行處理 對數組對象進行處理

1. 先定義一個對象

let obj = { name: 'jw'}

2. 定義一個監聽函數

/*** 判斷監聽的是否是對象* 如果是對象,就遍歷,并且對每個屬性進行定義get 和 set*/function observer(obj) { if(typeof obj === 'object') {  for (let key in obj) {  // defineReactive 方法設置get和set,見第三步   defineReactive(obj, key, obj[key]);  } }}

3.定義一個函數,處理每個屬性

function defineReactive(obj, key, value) { Object.defineProperty(obj, key, {  get() {   return value;  },  set(val) {   console.log('數據更新了')   value = val;  } })}

ok. 到這里初版已經實現了。嘗試一下吧

observer(obj);obj.name = 'haha'

控制臺輸出:
//數據更新了

以上已經實現設置obj的屬性的時候,被監聽到,并且可以去執行一些代碼了。但是,如果對象里面嵌入了對象呢?比如:

let obj = { name: 'jw', age: {  old: 60 }}

執行以下代碼

observer(obj);obj.age.old = '50'

控制臺輸出: 空

4.對監控的obj進行迭代處理

// 修改defineReactive , 添加一行代碼function defineReactive(obj, key, value) { // 如果對象的屬性也是一個對象。迭代處理 observer(value); Object.defineProperty(obj, key, {  //.... })}

再執行以下代碼:

observer(obj);obj.age.old = '50'

控制臺輸出:
//數據更新了

可惜的是,如果對象是一個數組,Object.defineProperty就無法起作用了,比如:

obj.skill = [1, 2, 3];obj.age.push(4);

控制臺輸出:
//空

實際上,不止push,包括slice,shift,unshif...都是沒有作用.

5. 重寫數組的方法

let arr = ['push', 'slice', 'shift', 'unshift'];arr.forEach(method=> { let oldPush = Array.prototype[method]; Array.prototype[method] = function(value) {  console.log('數據更新了')  oldPush.call(this, value) }})

再執行以下代碼:

obj.skill = [1, 2, 3];obj.skill.push(4);

控制臺輸出:
//數據更新了

但是,數組的length操作仍然是無效的。這也是為什么vue中只能通過方法去改變數組的原因了。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 集安市| 遂溪县| 枣阳市| 尚志市| 涞源县| 涞水县| 开原市| 施秉县| 长治县| 澜沧| 利津县| 宣城市| 庆云县| 博白县| 江川县| 洛扎县| 石棉县| 县级市| 洪湖市| 古田县| 灌南县| 杭锦旗| 沙雅县| 赤壁市| 瓦房店市| 洱源县| 松原市| 漳州市| 潞西市| 贺兰县| 新闻| 灯塔市| 无锡市| 万载县| 阳谷县| 鄂温| 弋阳县| 海南省| 南充市| 莎车县| 呼玛县|