摘要:在讀取訪問器屬性時,就會調(diào)用函數(shù),該函數(shù)負責(zé)返回有效的值在寫入訪問器屬性時,會調(diào)用函數(shù)并傳入新值,該函數(shù)負責(zé)決定如何處理數(shù)據(jù),但是這兩個函數(shù)不一定非要同時存在。
前言
Vue最明顯的特性之一便是它的響應(yīng)式系統(tǒng),其數(shù)據(jù)模型即是普通的 JavaScript 對象。而當(dāng)你讀取或?qū)懭胨鼈儠r,視圖便會進行響應(yīng)操作。文章簡要闡述下其實現(xiàn)原理,如有錯誤,還請不吝指正。個人博客鏈接:hiybm.cn
響應(yīng)式data
{{ message }}const vm = new Vue({ el: "#exp", data: { message: "This is A" } }) vm.message = "This is B" // 響應(yīng)式 vm._message = "This is C" // 非響應(yīng)式
上述代碼中,data是Vue實例的數(shù)據(jù)對象,當(dāng)實例初始化時,Vue 會遍歷 data 中的所有屬性,并且使用 Object.definePropery 把這些屬性全都轉(zhuǎn)為 getter/setter ,從而讓 data 的屬性能夠響應(yīng)數(shù)據(jù)變化。另外,Object.defineProperty 是 ES5 中一個無法 shim(墊片) 的特性,這也就是為什么 Vue 不支持 IE8 以及更低版本瀏覽器的原因。對象必須是純粹的對象 (含有零個或多個的 key/value 鍵值對):瀏覽器 API 創(chuàng)建的原生對象。所以,在data中聲明過的message是響應(yīng)式數(shù)據(jù),而由于_message是在data外使用 Vue 實例增加的數(shù)據(jù),所以亦不屬于響應(yīng)式。
關(guān)于Object.definePropery
Object.defineProperty() 方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現(xiàn)有屬性,并返回這個對象。這個API是實現(xiàn)響應(yīng)式數(shù)據(jù)的關(guān)鍵所在。
Syntax: Object.defineProperty(obj, prop, descriptor)
obj: 要定義屬性的對象
prop: 要定義或修改的屬性的名稱
descriptor: 將被定義或修改的屬性描述符。
Tips: 要知道ECMAScript中有兩種屬性:數(shù)據(jù)屬性和訪問器屬性。這里的descriptor可取值有數(shù)據(jù)屬性和訪問器屬性。
數(shù)據(jù)屬性: 包含一個數(shù)據(jù)值的位置,在此位置可以進行讀寫操作,有以下特性:
[[Configurable]]:對屬性的操作可配置性開關(guān),如刪除,修改。默認值為true。
[[Enumberble]]:是否可枚舉(通過for-in)。默認值為true。
[[Writable]]:能否修改屬性的值。默認值為true。
[[value]]:包含這個屬性的數(shù)據(jù)值,讀取時從該位置讀,寫入時把新值存到該位置。默認值為undefined。
訪問器屬性: 不包含數(shù)據(jù)值,包含一個函數(shù)對(getter/setter)。特性如下:
[[Configurable]]:對屬性的操作可配置性開關(guān),如刪除,修改。默認值為true。
[[Enumberble]]:是否可枚舉(通過for-in)。默認值為true。
[[Get]]:讀取屬性時調(diào)用的函數(shù)。默認值為undefined。
[[Set]]:寫入屬性時調(diào)用的函數(shù)。默認值為undefined。
Tips: 在讀取訪問器屬性時,就會調(diào)用getter函數(shù),該函數(shù)負責(zé)返回有效的值;在寫入訪問器屬性時,會調(diào)用setter函數(shù)并傳入新值,該函數(shù)負責(zé)決定如何處理數(shù)據(jù),但是這兩個函數(shù)不一定非要同時存在。Vue便是利用getter/setter這一特性來實現(xiàn)的響應(yīng)系統(tǒng)。
示例代碼:
// 定義一個book對象,_year和edition都屬于數(shù)據(jù)屬性。 var book = { _year : 2004, edition : 1 }; // 對book對象創(chuàng)建 year 訪問器屬性。 Object.defineProperty(book, "year",{ // 讀取 year 訪問器屬性時,get() 方法返回 _year 的值。 get : function () { console.info(this._year, "get"); // 2004 return this._year; }, // 寫入 year 訪問器屬性時,set() 方法對新值進行操作。 set : function (newValue) { if (newValue > 2004) { this._year = newValue; console.info(this._year, "set") // 2005 this.edition += newValue - 2004; } } }); // 讀取 year 訪問器屬性時會返回_year的值。 book.year; // 寫入 year 訪問器屬性時會調(diào)用set() 函數(shù),進行操作。 book.year = 2005; console.info(book.edition) // 2 console.info(book) // 此處藏有彩蛋。
watcher
官方表述:每個組件實例都有相應(yīng)的 watcher 實例對象,它會在組件渲染的過程中把屬性記錄為依賴,之后當(dāng)依賴項的 setter 被調(diào)用時,會通知 watcher 重新計算,從而致使它關(guān)聯(lián)的組件得以更新。
如下圖所示:
Tips:模板中每個指令/數(shù)據(jù)綁定都有一個對應(yīng)的 watcher 對象。其中 watcher扮演的角色相當(dāng)于是一個紐帶,這個紐帶的作用就是依賴收集。
END
文中還有部分深層細節(jié)沒有講述到,后續(xù)我也會接著更新系列文章來進一步深深深究vue底層的響應(yīng)式原理,SYNT。BTW,如果有同學(xué)發(fā)現(xiàn)彩蛋了,歡迎在評論區(qū)交流。?
參考鏈接
Object.defineproperty
深入響應(yīng)式原理
深入淺出之vue響應(yīng)式原理
Javascript高級程序設(shè)計(第3版)6.1章節(jié)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/90258.html
摘要:問題為什么修改即可觸發(fā)更新和的關(guān)聯(lián)關(guān)系官方介紹的官網(wǎng)文檔,對響應(yīng)式屬性的原理有一個介紹。因此本文在源碼層面,對響應(yīng)式原理進行梳理,對關(guān)鍵步驟進行解析。 描述 ?我們通過一個簡單的 Vue應(yīng)用 來演示 Vue的響應(yīng)式屬性: html: {{message}} js: let vm = new Vue({ el: #ap...
摘要:所以我今后打算把每一個內(nèi)容分成白話版和源碼版。有什么錯誤的地方,感謝大家能夠指出響應(yīng)式系統(tǒng)我們都知道,只要在實例中聲明過的數(shù)據(jù),那么這個數(shù)據(jù)就是響應(yīng)式的。什么是響應(yīng)式,也即是說,數(shù)據(jù)發(fā)生改變的時候,視圖會重新渲染,匹配更新為最新的值。 寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 V...
寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關(guān)注公眾號也可以吧 【Vue原理】Props - 源碼版 今天記錄 Props 源碼流程,哎,這東西,就算是研究過了,也真是會隨著時間慢慢忘記的。 幸好我做...
摘要:原型方法通過原型方法方法來掛載實例。當(dāng)響應(yīng)式屬性發(fā)生變化時,會通知依賴列表中的對象進行更新。此時,對象執(zhí)行方法,重新渲染節(jié)點。在執(zhí)行過程中,如果需要讀取響應(yīng)式屬性,則會觸發(fā)響應(yīng)式屬性的??偨Y(jié)響應(yīng)式屬性的原理 vue實例 初始化 完成以后,接下來就要進行 掛載。 vue實例掛載,即為將vue實例對應(yīng)的 template模板,渲染成 Dom節(jié)點。 原型方法 - $mount ? 通過原...
摘要:對象用戶看到的對象用戶看到的是這個對象即是實際使用的對象實際使用的對象復(fù)制更新相應(yīng)的代碼實現(xiàn)對象代理響應(yīng)式原理前提官網(wǎng)說過,限于現(xiàn)代瀏覽器限制,無法監(jiān)測通過這種方式添加的屬性,所以,他的響應(yīng)式是建立在實例化對象的時候,預(yù)定義屬性的基礎(chǔ)上的。 1. Vue 對象 1.1 用戶看到的對象 var app = new Vue({ el: #app , /* * 用...
閱讀 3056·2023-04-25 20:09
閱讀 3328·2021-11-23 09:51
閱讀 1981·2021-11-22 15:25
閱讀 3362·2021-11-18 10:02
閱讀 2761·2021-09-27 13:56
閱讀 1317·2019-08-30 15:44
閱讀 1158·2019-08-30 13:21
閱讀 3332·2019-08-30 11:05