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

首頁 > 語言 > JavaScript > 正文

深入淺出 Vue 系列 -- 數據劫持實現原理

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

一、前言

數據雙向綁定作為 Vue 核心功能之一,其實現原理主要分為兩部分:

    數據劫持 發布訂閱模式

本篇文章主要介紹 Vue 實現數據劫持的思路,下一篇則會介紹發布訂閱模式的設計。

二、針對 Object 類型的劫持

對于 Object 類型,主要劫持其屬性的讀取與設置操作。在 JavaScript 中對象的屬性主要由一個字符串類型的“名稱”以及一個“屬性描述符”組成,屬性描述符包括以下選項:

    value: 該屬性的值; writable: 僅當值為 true 時表示該屬性可以被改變; get: getter (讀取器); set: setter (設置器); configurable: 僅當值為 true 時,該屬性可以被刪除以及屬性描述符可以被改變; enumerable: 僅當值為 true 時,該屬性可以被枚舉。

上述 setter 和 getter 方法就是供開發者自定義屬性的讀取與設置操作,而設置對象屬性的描述符則少不了 Object.defineProperty() 方法:

function defineReactive (obj, key) { let val = obj[key] Object.defineProperty(obj, key, {  get () {   console.log(' === 收集依賴 === ')   console.log(' 當前值為:' + val)   return val  },  set (newValue) {   console.log(' === 通知變更 === ')   console.log(' 當前值為:' + newValue)   val = newValue  } })}const student = { name: 'xiaoming'}defineReactive(student, 'name') // 劫持 name 屬性的讀取和設置操作

上述代碼通過 Object.defineProperty() 方法設置屬性的 setter 與 getter 方法,從而達到劫持 student 對象中的 name 屬性的讀取和設置操作的目的。

讀者可以發現,該方法每次只能設置一個屬性,那么就需要遍歷對象來完成其屬性的配置:

 Object.keys(student).forEach(key => defineReactive(student, key))

另外還必須是一個具體的屬性,這也非常的致命。

假如后續需要擴展該對象,那么就必須手動為新屬性設置 setter 和 getter 方法,**這就是為什么不在 data 中聲明的屬性無法自動擁有雙向綁定效果的原因 **。(這時需要調用 Vue.set() 手動設置)

以上便是對象劫持的核心實現,但是還有以下重要的細節需要注意:

1、屬性描述符 - configurable

在 JavaScript 中,對象通過字面量創建時,其屬性描述符默認如下:

const foo = { name: '123'}Object.getOwnPropertyDescriptor(foo, 'name') // { value: '123', writable: true, enumerable: true, configurable: true }

前面也提到了 configurable 的值如果為 false,則無法再修改該屬性的描述符,所以在設置 setter 和 getter 方法時,需要注意 configurable 選項的取值,否則在使用 Object.defineProperty() 方法時會拋出異常:

// 部分重復代碼 這里就不再羅列了。function defineReactive (obj, key) { // ... const desc = Object.getOwnPropertyDescriptor(obj, key) if (desc && desc.configurable === false) {  return } // ...}            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 城步| 崇文区| 鱼台县| 南岸区| 阆中市| 双鸭山市| 大邑县| 临漳县| 绥化市| 浏阳市| 咸丰县| 平江县| 孝感市| 颍上县| 桂平市| 正镶白旗| 定边县| 阳新县| 玉龙| 突泉县| 资兴市| 白河县| 子长县| 孟连| 抚松县| 盖州市| 巴彦县| 新宾| 庆阳市| 普兰县| 长宁县| 衡阳县| 辽中县| 贵定县| 大悟县| 庄浪县| 博白县| 蒙山县| 资阳市| 云梦县| 阜新市|