首頁  >  文章  >  web前端  >  vue.js雙向綁定是什麼

vue.js雙向綁定是什麼

coldplay.xixi
coldplay.xixi原創
2020-11-10 14:19:432828瀏覽

vue.js雙向綁定:存取器屬性是物件中的一種特殊屬性,它不能直接在物件中設置,而必須透過 【defineProperty()】方法單獨定義。

vue.js雙向綁定是什麼

本教學操作環境:windows10系統、vue2.9,本文適用於所有品牌的電腦。

【相關文章推薦:vue.js

#一、存取器屬性

#存取器屬性是物件中的一種特殊屬性,它不能直接在物件中設置,而必須透過defineProperty() 方法單獨定義。

       var obj = { };
       // 为obj定义一个名为 hello 的访问器属性
       Object.defineProperty(obj, "hello", {
         get: function () {return sth},
         set: function (val) {/* do sth */}
       })

       obj.hello# // 可以像一般屬性一樣讀取存取器屬性

       存取器屬性的"值"較為特殊,讀取或設定存取器屬性的值,實際上是呼叫其內部特性:get和set函數。

       obj.hello // 讀取屬性,就是呼叫get函數並傳回get函數的回傳值

       obj.hello = "abc" // 要為屬性賦值,就是呼叫set函數,賦值其實是傳參 

       get 與set 方法內部的this 都指向obj,這表示get 與set 函數可以操作物件內部的值。另外,訪問器屬性的會"覆蓋"同名的普通屬性,因為訪問器屬性會被優先訪問,與其同名的普通屬性則會被忽略。

二、極簡雙向綁定的實作

#       此範例所實現的效果是:隨文字方塊輸入文字的變化,span 中會同步顯示相同的文字內容;在js或控制台明確的修改obj.hello 的值,視圖會相應更新。這樣就實現了 model => view 以及 view => model 的雙向綁定。

       以上就是 Vue 實現雙向綁定的基本原則。

三、分解任務

       上述範例只是為了說明原則。我們最終要實現的是:

       先將該任務分成幾個子任務:

#   1、輸入框以及文字節點與data 中的資料綁定

   2、輸入框內容變化時,data 中的資料同步變化。即 view => model 的變化。

   3、data 中的資料變化時,文字節點的內容同步變化。即 model => view 的變化。

       要實現任務一,需要對 DOM 進行編譯,這裡有一個知識點:DocumentFragment。

四、DocumentFragment

       DocumentFragment(文檔片段)可以看作節點容器,它可以包含多個子節點,當我們將它插入DOM 時,只有它的子節點會插入目標節點,所以把它看成一組節點的容器。使用 DocumentFragment 處理節點,速度和效能遠優於直接操作 DOM。 Vue 編譯時,就是將掛載目標的所有子節點劫持(真的是劫持,透過 append 方法,DOM 中的節點會被自動刪除)到DocumentFragment 中,經過一番處理後,再將DocumentFragment 整體回傳插入掛載目標。

# 勘誤:flag.append() 應為 flag.appendChild()。下同。在 Chrome 中用 append() 竟然正常,沒報錯。

      

#五、資料初始化綁定

################################################ ################       以上程式碼實現了任務一,我們可以看到,hello world已經呈現在輸入框和文字節點中。 ###

 

六、響應式的資料綁定

       再來看任務二的實現想法:當我們在輸入當框輸入資料的時候,先觸發input 事件(或keyup、change 事件),在對應的事件處理程序中,我們取得輸入框的value 並賦值給vm 實例的text 屬性。我們會利用 defineProperty 將 data 中的 text 設定為 vm 的存取器屬性,因此給 vm.text 賦值,就會觸發 set 方法。在 set 方法中主要做兩件事,第一是更新屬性的值,第二留到任務三再說。

       任務二也完成了,text 屬性值會與輸入方塊的內容同步變化:

七、訂閱/發布模式(subscribe&publish)

       text 屬性變更了,set 方法觸發了,但文字節點的內容沒有變化。如何讓同樣綁定到 text 的文字節點也同步變化呢?這裡又有一個知識點:訂閱發布模式。

       訂閱發佈模式(又稱為觀察者模式)定義了一種一對多的關係,讓多個觀察者同時監聽某一個主題對象,而這個主題對象的狀態改變時就會通知所有觀察者對象。

       發佈者發出通知=> 主題對象收到通知並推送給訂閱者=> 訂閱者執行對應操作

       先前提到的,當set 方法觸發後做的第二件事就是作為發布者發出通知:「我是屬性text,我改變了」。文字節點則是作為訂閱者,在收到訊息後執行對應的更新操作。

八、雙向綁定的實作

       回顧一下,每當new 一個Vue,主要做了兩件事:第一個是監聽資料:observe( data),第二個是編譯HTML:nodeToFragement(id)。

       在監聽資料的過程中,會為 data 中的每一個屬性產生一個主題物件 dep。

       在編譯 HTML 的過程中,會為每個與資料綁定相關的節點產生一個訂閱者 watcher,watcher 會將自己加入對應屬性的 dep 中。

       我們實現:修改輸入框內容 => 在事件回呼函數中修改屬性值 => 觸發屬性的 set 方法。

       接下來我們要實現的是:發出通知 dep.notify() => 觸發訂閱者的 update 方法 => 更新視圖。

       這裡的關鍵邏輯是:如何將 watcher 加入到關聯屬性的 dep 中。

       在編譯 HTML 過程中,為每個與 data 相關的節點產生一個 Watcher。 Watcher 函數中發生了什麼事?

       首先,將自己賦給了一個全域變數Dep.target;

       其次,執行了update 方法,進而執行了get 方法,get 的方法讀取了vm 的存取器屬性,從而觸發了存取器屬性的get 方法,get 方法中將該watcher 新增至了對應存取器屬性的dep 中;

       再次,取得屬性的值,然後更新視圖。

       最後,將 Dep.target 設為空白。因為它是全域變量,也是 watcher 與 dep 關聯的唯一橋樑,任何時刻都必須保證 Dep.target 只有一個值。

       至此,hello world 雙向綁定基本上實作了。文字內容會隨輸入框內容同步變化,在控制器中修改 vm.text 的值,會同步反映在文字內容中。

相關免費學習推薦:JavaScript(影片)

以上是vue.js雙向綁定是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn