Vue數據雙向綁定(面試必備) 極簡版

  我又來吹牛逼了,此次咱們簡單說一下vue的數據雙向綁定,咱們此次不背題,而是要你理解這個流程,保證讀完就懂,逢人能講,面試必過,若是沒作到,請再來看一遍,走起:html

  

  介紹雙向數據以前,咱們先解釋幾個名詞:vue

 

  一、什麼是setter、getter ?面試

  答:首先,別誤覺得他們就是一會要說的get、set,咱們先看一句定義:segmentfault

    對象有兩種屬性:(1)數據屬性,就是咱們常常使用的屬性(2)訪問器屬性,也稱存取器屬性(存取器屬性就是一組獲取和設置值的函數數組

   

  再看一行代碼:函數

  

  log打印出來的以下:ui

  

  數據屬性就是a和b;spa

  get和set就是關鍵字 它們後面各自對應一個函數,這個函數就是上面紅字部分所講的,存儲器屬性。雙向綁定

  get對應的方法稱爲getter,負責獲取值,它不帶任何參數。set對應的方法爲setter,負責設置值,在它的函數體中,一切的return都是無效的。code

 

  2、什麼是Object.defineProperty() ?

  答:老規矩走起,咱們先看一句定義:

  對象是由多個名/值對組成的無序的集合。對象中每一個屬性對應任意類型的值。

  

  定義對象能夠使用構造函數或字面量的形式:

  

  

  除了以上添加屬性的方式,固然還能夠使用Object.defineProperty定義新屬性或修改原有的屬性;

  語法:

  Object.defineProperty(obj, prop, descriptor)

  參數:

  obj:必需。目標對象;
  prop:必需。需定義或修改的屬性的名字;
  descriptor:必需。目標屬性所擁有的特性;

  返回值:

  傳入函數的對象,即第一個參數obj;

 

  OK,定義介紹完了,咱們如今說一下一會關於雙向綁定咱們要用到的知識點:存取器描述;(誒?你是否是發現和上面好像有點關係)

  

  對頭,它是這樣使用的:

  

 

  如今不管是你獲取仍是設置咱們均可以接到通知,是否是有一點雙向數據綁定的影子了,別急下面還有;

  

  OK,我終於叨叨完沒用的了,如今開始說正題,如何理解Vue的雙向數據綁定,哈哈,先來一個定義:

  Vue是採用數據劫持結合發佈/訂閱模式的方式,經過Object.defineProperty()來劫持各個屬性的settergetter,在數據變更時發佈消息給訂閱者,觸發相應的監聽回調。

 

  咱們來看一個很粗暴的栗子,low版雙向綁定:

  

 

  是否是有點明白了呢,固然這也不是所有,咱們剛剛說的大概就是下面Observer的部分,對每一個vue中的data中定義的屬性循環用Object.defineProperty()實現數據劫持,以便利用其中的setter和getter,而後通知訂閱者,訂閱者會觸發它的update方法,對視圖進行更新。

 

  

 

  別急,下面也很簡單:

  Dep,它就像一個依賴管理同樣,小夥伴又問啥是依賴管理倪? 上圖!

  

  我用一個例子來解釋一下上面這張圖 下面高能預警:

  在vue中v-model,v-name,{{}}等均可以對數據進行展現,也就是說假如一個屬性都經過這三個指令了,那麼每當這個屬性改變的時候,相應的這個三個指令的html視圖也必須改變;

  因而vue中就是每當有這樣的可能用到雙向綁定的指令,就在一個Dep中增長一個訂閱者(addSub),其訂閱者只是更新本身的指令對應的數據,也就是v-model='name'和{{name}}有兩個對應的訂閱者,各自管理本身的地方;

  每當屬性的set方法觸發,就循環更新Dep中的訂閱者(notify);

 

  OK,Dep是否是很明白了呢

  集合上面的那張圖來看,就是Observer一旦有了set觸發,就會通知到Dep,那Dep接到通知以後呢?從圖上來看,下面所講的就應該是Compile了,也很簡單:

  首先,先要知道它負責幹什麼?

  compile主要作的事情是解析模板指令,將模板中的變量替換成數據

  其次知道它何時要工做,只有兩種狀況,先上圖:

  

  

  1)初始化,init的時候 初始化渲染頁面視圖;

  2)將每一個指令對應的節點綁定更新函數,添加監聽數據的訂閱者

 

  Dep負責維護依賴,而訂閱者則來自於compile,一旦有數據變更,則會綁定更新函數,此時也就是產生了訂閱者,這個時候Dep內就增長了一個訂閱者,而一旦數據變更,則會收到通知,更新視圖;

 

  好了,你是否是以爲上面這行說不通,或是讀不通,固然,由於上面的這個流程了缺乏了,咱們最後要說的Watcher我把上面這句話補全,就是Watcher的工做了;

 

  Dep負責維護依賴,而訂閱者則來自於compile,一旦有數據變更,則會經過Watcher綁定更新函數,此時Watcher也向Dep中添加了訂閱者,一旦Dep接到Observer的通知,它就會再去通知WatcherWatcher則會調用自身的update()方法,並觸發Compile中綁定的回調,更新視圖;

 

  

  最後敲黑板:

  首先咱們爲每一個vue屬性用Object.defineProperty()實現數據劫持,爲每一個屬性分配一個訂閱者集合的管理數組dep;

  而後在編譯的時候在該屬性的數組dep中添加訂閱者,v-model會添加一個訂閱者,{{}}也會,v-bind也會,只要用到該屬性的指令理論上都會;

  接着爲input會添加監聽事件,修改值就等於爲該屬性賦值,則會觸發該屬性的set方法,在set方法內通知訂閱者數組dep,訂閱者數組循環調用各訂閱者的update方法更新視圖。

 

  參考乾貨:

  http://www.javashuo.com/article/p-ancuiebz-x.html

  http://www.javashuo.com/article/p-brudryzf-hq.html

 

  感謝巨人的肩膀

相關文章
相關標籤/搜索