Vue響應式系統的原理詳解

vue響應式系統的基本原理

我們使用vue時,對數據進行操作,就能影響對應的視圖。那麼這種機制是怎麼實現的呢?

思考一下,是不是就好像我們對數據的操作 被“某人”監視瞭?一旦我們對數據進行瞭更改,“某人”就能感應到,並幫我們更新視圖

那麼這個“某人”到底是誰呢?其實它很普通,就是我們基礎裡面有學過的 Object.defineProperty,使用它來對數據進行一下加工,就能實現當數據被讀時,執行“讀”的回調函數;數據被寫時,執行“寫”的回調函數。

接下來,我們將簡單回顧該方法的使用,再用幾個實戰小例子帶大傢徹底弄懂這個原理。

1.回顧一下Object.defineProperty的用法

參數解釋:

	obj: 目標對象
	prop: 需要操作的目標對象的屬性名
	descriptor: 描述符
	
	return value 傳入對象

descriptor的一些屬性,簡單介紹幾個屬性。

	enumerable,屬性是否可枚舉,默認 false。
	configurable,屬性是否可以被修改或者刪除,默認 false。
	writable,屬性是否可以被修改,默認false
	get,獲取屬性的方法。
	set,設置屬性的方法。

完整用法:

	Object.defineProperty(obj, prop, descriptor)

2.實戰1:使用 Object.defineProperty 對 person的age屬性 進行監聽

踩坑

看下面代碼,乍一看是不是感覺沒什麼不妥?

當有人讀取person的age屬性時,我就把person的age屬性return出去;當有人修改person的age屬性,我就直接修改person.age的值。

在這裡插入圖片描述

但是!同學們,運行瞭一下,雖然沒報錯,但是編譯器一直瘋狂輸出“@@有人讀取瞭age屬性”。

在這裡插入圖片描述

這是為啥呢?你想想,你在get函數裡面直接return person.age,這算不算又一次讀取瞭person的age屬性呢?此時程序又去執行age的get函數,反反復復。

打個比方哈,相當於 你想讀取age,於是你告訴編譯器,我要輸出person.age,好的,編譯器去查person.age,發現它有get函數,於是執行get函數,此時你以為你要拿到它的值瞭,沒想到get函數裡面又告訴編譯器,我要person.age。這樣的話,就形成瞭死循環!!

那要怎麼解決呢?我在get裡面不能直接返回 person.age,那我要怎麼拿到這個屬性的值呢?

:是不是可以用變量來替代呢?

我把person.age的值放在變量ageNumber中,我要讀的時候,就返回ageNumber的值;要修改的時候,就修改ageNumber的值;

這樣不就避免瞭在get,set函數裡面直接用person.age來訪問嗎?

正確代碼

在這裡插入圖片描述

這時,效果就完成瞭,讀取和修改的時候,都能被監聽到。

在這裡插入圖片描述

3.數據代理

數據代理是什麼意思呢?

答:簡單解釋一下,就是通過一個對象 代理 對另一個對象中屬性的操作 (讀/寫)

有點抽象對嗎?用下面的小例子來解釋一下吧。

在這裡插入圖片描述

在這裡插入圖片描述

當老師想查看 或者 修改學生的成績時,直接在老師這個對象上操作就行瞭,不需要直接去操作student對象。

這也就是上面想解釋的,通過 老師對象(teacher) 代理 瞭學生對象(student)中的成績屬性(score)的操作 (讀/寫)

4.vue中實現響應式思路

有一點vue2基礎的同學們應該知道,我們在vue中data() {} 中定義的數據,是不是都會被掛載到vm對象上去?然後我們是通過 this.數據名 來對數據進行操作的,對嗎?

那這個是不是就相當於上面的小例子中的情景呢,這裡是vm對象   代理   你定義的data對象中的屬性的操作(讀/寫)

再用個例子完整實現一下vue的響應式原理

把data對象中的所有屬性 交給 vm對象進行代理(讓vm 掌控data對象中的屬性的 (讀/寫) 操作 )當數據變化時,能更新對應視圖

總結

1.Vue中的數據代理:

通過vm對象來代理data對象中屬性的操作(讀/寫)

2.Vue中數據代理的好處:

更加方便的操作data中的數據

3.基本原理:

通過Object.defineProperty()把data對象中所有屬性添加到vm上。

為每一個添加到vm上的屬性,都指定一個getter/setter。

getter/setter內部去操作(讀/寫)data中對應的屬性。

4.vue中實現響應式思路

不使用數據代理,直接把數據 賦值 掛載到vm上。

1.下圖的方法是對 數據對象設置get,set的通用方法

在這裡插入圖片描述

2.在new一個Vue時,就會直接把用戶傳入的data對象,掛載到Vue實例身上

再對Vue實例上面的data對象進行監視(響應式處理)

在這裡插入圖片描述

在這裡插入圖片描述

本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!

推薦閱讀: