在面試一些大廠的時候,面試官可能會問到你vue雙向資料繫結的原理是什麼?有些小夥伴不知道是什麼東西,這樣你在面試官的眼裡就大打折扣了。今天小千就來給大家介紹一下vue的雙向繫結原理,千萬不要錯過啦。
vue雙向繫結
大家其實對於這個問題不會很陌生,vue中採用mvvm的模式,內建vm將view層與model層兩者進行關聯,任何一方的變化都會讓另外一方受到影響。那回答完後,面試官還會繼續追問,請回答一下你理解的雙向資料繫結背後的原理是什麼?那今天我們就一起**一下vue的背後的一些方式實現。
所謂要實現雙向資料繫結,vue中內部採用了發布-訂閱模式。內部結合了object.defineproperty這個es5的新特性(ie8瀏覽器可不支援哦…),對vue傳入的資料進行了相應的資料攔截,為其動態新增get與set方法。當資料變化的時候,就會觸發對應的set方法,當set方法觸發完成的時候,內部會進一步觸發watcher,當資料改變了,接著進行虛擬dom對比,執行render,後續檢視更新操作完畢。
來,直接上圖看一下
好,分析完原理後,我們來看下es5這個方法object.defineproperty有什麼用呢?
上**執行一下:
執行的時候,我們不難發現,輸入框裡面的內容改變的時候,p標籤裡面的值也會對應的得到變化。原因是因為當輸入框的內容發生變化的時候,我們獲取到了輸入框的值,然後將其賦值給object.msg屬性。這樣object的msg屬性的set方法就會被執行,從而將對應的content值進行了改變。
那後續當我們去修改資料,檢視會不會自動更新呢?
這樣,整了乙個定時器,過了2s中,修改了物件的資料,物件資料發生變化,從而又會觸發set方法,實現了響應的資料改變,檢視也會變成了hello-world的值。其實,這就是借助了vue中的object.defineproperty對於資料的攔截處理的流程。
補充小貼士
vue 2.x中使用的object.defineproperty對於資料進行攔截,其實還是有缺陷的
1、物件屬性的新加或者刪除無法監聽;
2、陣列元素的增加和刪除無法監聽。
那為啥2.x的時候不解決呢,從兩點考慮:
1.效能:通過遍歷物件的屬性進行監聽,但是屬性值也是物件就需要深度遍歷了,這時候顯然能夠劫持完整物件更好
2.無法監聽陣列:屬性值改為陣列,陣列也算是一種特殊的物件,下標其實就是物件的屬性,理論上是可以通過
object.defineproperty來處理的,那尤大大為什麼沒有採用這種方式呢,猜測源於陣列的使用場景,陣列的主要操作場景是遍歷,如果每乙個元素都掛載set和get方法,會產生巨大效能消耗,而且陣列下標變化頻繁,操作方法居多,一旦陣列長度發生變化,在無法自動檢測的狀態下,手動更新會是乙個相當繁瑣的工作。
那vue中是如何實現對陣列的劫持呢,對7種常用的陣列操作進行了重寫,分別是push() 、pop() 、shift()、 unshift() 、splice() 、sort()、 reverse(),其中vue.set()對於陣列的處理其實就是呼叫了splice方法。
針對object.defineproperty的缺點,es6 proxy都能夠完美得解決,它唯一的缺 點就是,對ie不友好,所以vue3在檢測到如果是使用ie的情況下(沒錯,ie11都不支援proxy),會自動降級為object.defineproperty的資料監聽系統。
那麼到這一步,恭喜哦!你已經明白了vue2.x的雙向資料繫結原理了。
vue雙向繫結原理
大家知道vue的雙向繫結原理是利用object.defineproperty 這一方法,以下是我研究該方法的一些內容 語法 object.defineproperty obj,prop,descriptor descriptor是將被定義或修改的屬性描述符,而雙向繫結是利用get和set屬性描述符。...
Vue雙向繫結原理
vue實現資料雙向繫結的原理就是用object.defineproperty 重新定義 set方法 物件設定屬性值和 get方法 獲取屬性值的操縱來實現的 object.property 方法的解釋 object.property 引數1,引數2,引數3 返回值為該物件obj 其中引數1為該物件 o...
vue雙向繫結原理
vue資料雙向繫結是通過資料劫持結合發布者 訂閱者模式來實現的。首先要對資料進行劫持監聽,所以需要設定乙個 observer,用來監聽所有的屬性。如果屬性發生了變化,就要告訴訂閱者watcher看是否需要更新,因為訂閱者很多,所以我們需要有乙個訊息訂閱器容器dep專門收集訂閱者,然後在 observ...