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的更多內容!
推薦閱讀:
- JavaScript Object.defineProperty與proxy代理模式的使用詳細分析
- Vue中的數據驅動解釋
- vue.js數據響應式原理解析
- 利用js實現Vue2.0中數據的雙向綁定功能
- 一文讀懂JavaScript 中的延遲加載屬性模式