最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue.js雙向綁定實現原理詳解

 更新時間:2016年12月22日 09:37:34   作者:kidney  
這篇文章主要為大家詳細介紹了Vue.js雙向綁定實現原理,具有一定的參考價值,感興趣的小伙伴們可以參考一下

Vue.js最核心的功能有兩個,一是響應式的數據綁定系統(tǒng),二是組件系統(tǒng)。本文僅探究幾乎所有Vue的開篇介紹都會提到的hello world雙向綁定是怎樣實現的。先講涉及的知識點,再參考源碼,用盡可能少的代碼實現那個hello world開篇示例。

參考文章:http://www.fzitv.net/article/100819.htm

一、訪問器屬性

訪問器屬性是對象中的一種特殊屬性,它不能直接在對象中設置,而必須通過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函數可以操作對象內部的值。另外,訪問器屬性的會"覆蓋"同名的普通屬性,因為訪問器屬性會被優(yōu)先訪問,與其同名的普通屬性則會被忽略(也就是所謂的被"劫持"了)。

二、極簡雙向綁定的實現

此例實現的效果是:隨文本框輸入文字的變化,span中會同步顯示相同的文字內容;在js或控制臺顯式的修改obj.name的值,視圖會相應更新。這樣就實現了model =>view以及view => model的雙向綁定,并且是響應式的。

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

三、分解任務

上述示例僅僅是為了說明原理。我們最終要實現的是:

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

   1、輸入框以及文本節(jié)點與data中的數據綁定

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

   3、data中的數據變化時,文本節(jié)點的內容同步變化。即model => view的變化。

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

四、DocumentFragment

DocumentFragment(文檔片段)可以看作節(jié)點容器,它可以包含多個子節(jié)點,當我們將它插入到DOM中時,只有它的子節(jié)點會插入目標節(jié)點,所以把它看作一組節(jié)點的容器。使用DocumentFragment處理節(jié)點,速度和性能遠遠優(yōu)于直接操作DOM。Vue進行編譯時,就是將掛載目標的所有子節(jié)點劫持(真的是劫持)到DocumentFragment中,經過一番處理后,再將DocumentFragment整體返回插入掛載目標。

五、數據初始化綁定

以上代碼實現了任務一,我們可以看到,hello world已經呈現在輸入框和文本節(jié)點中。

六、響應式的數據綁定

再來看任務二的實現思路:當我們在輸入框輸入數據的時候,首先觸發(fā)input事件(或者keyup、change事件),在相應的事件處理程序中,我們獲取輸入框的value并賦值給vm實例的text屬性。我們會利用defineProperty將data中的text劫持為vm的訪問器屬性,因此給vm.text賦值,就會觸發(fā)set方法。在set方法中主要做兩件事,第一是更新屬性的值,第二留到任務三再說。

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

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

text屬性變化了,set方法觸發(fā)了,但是文本節(jié)點的內容沒有變化。如何讓同樣綁定到text的文本節(jié)點也同步變化呢?這里又有一個知識點:訂閱發(fā)布模式。

訂閱發(fā)布模式(又稱觀察者模式)定義了一種一對多的關系,讓多個觀察者同時監(jiān)聽某一個主題對象,這個主題對象的狀態(tài)發(fā)生改變時就會通知所有觀察者對象。

發(fā)布者發(fā)出通知 => 主題對象收到通知并推送給訂閱者 => 訂閱者執(zhí)行相應操作

之前提到的,當set方法觸發(fā)后做的第二件事就是作為發(fā)布者發(fā)出通知:“我是屬性text,我變了”。文本節(jié)點則是作為訂閱者,在收到消息后執(zhí)行相應的更新操作。

八、雙向綁定的實現

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

在監(jiān)聽數據的過程中,會為data中的每一個屬性生成一個主題對象dep。

在編譯HTML的過程中,會為每個與數據綁定相關的節(jié)點生成一個訂閱者watcher,watcher會將自己添加到相應屬性的dep中。

我們已經實現:修改輸入框內容 => 在事件回調函數中修改屬性值 => 觸發(fā)屬性的set方法。

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

這里的關鍵邏輯是:如何將watcher添加到關聯(lián)屬性的dep中。

在編譯HTML過程中,為每個與data關聯(lián)的節(jié)點生成一個Watcher。Watcher函數中發(fā)生了什么呢?

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

其次,執(zhí)行了update方法,進而執(zhí)行了get方法,get的方法讀取了vm的訪問器屬性,從而觸發(fā)了訪問器屬性的get方法,get方法中將該watcher添加到了對應訪問器屬性的dep中;

再次,獲取屬性的值,然后更新視圖。

最后,將Dep.target設為空。因為它是全局變量,也是watcher與dep關聯(lián)的唯一橋梁,任何時刻都必須保證Dep.target只有一個值。

至此,hello world雙向綁定就基本實現了。文本內容會隨輸入框內容同步變化,在控制器中修改vm.text的值,會同步反映到文本內容中(但輸入框還沒有綁定,讀者可以自己試試)。

完整代碼:https://github.com/bison1994/two-way-data-binding

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • 使用vue控制元素顯示隱藏方式

    使用vue控制元素顯示隱藏方式

    這篇文章主要介紹了使用vue控制元素顯示隱藏方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Vue引入Stylus知識點總結

    Vue引入Stylus知識點總結

    在本篇文章里小編給各位整理的是一篇關于Vue引入Stylus知識點總結內容,有需要的朋友們可以學習參考下。
    2020-01-01
  • 基于vue cli重構多頁面腳手架過程詳解

    基于vue cli重構多頁面腳手架過程詳解

    本文分步驟給大家介紹了基于vue cli重構多頁面腳手架過程,非常不錯,具有參考借鑒價值,需要的朋友參考下
    2018-01-01
  • vue-router鉤子執(zhí)行順序示例解析

    vue-router鉤子執(zhí)行順序示例解析

    這篇文章主要為大家介紹了vue-router鉤子執(zhí)行順序示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • axios實現文件上傳并獲取進度

    axios實現文件上傳并獲取進度

    這篇文章主要為大家詳細介紹了axios實現文件上傳并獲取進度,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • VUE3使用JSON編輯器方式

    VUE3使用JSON編輯器方式

    這篇文章主要介紹了VUE3使用JSON編輯器方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • 五分鐘理解keep?alive用法及原理

    五分鐘理解keep?alive用法及原理

    這篇文章主要為大家介紹了keep?alive用法及原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • vue3中setup語法糖下父子組件間傳遞數據的方式

    vue3中setup語法糖下父子組件間傳遞數據的方式

    Vue3中父組件指的是包含一個或多個子組件的組件,它們通過props和事件等方式來傳遞數據和通信,這篇文章主要介紹了vue3中setup語法糖下父子組件間傳遞數據的方式,需要的朋友可以參考下
    2023-06-06
  • Vue通過moment插件實現獲取當前月的第一天和最后一天

    Vue通過moment插件實現獲取當前月的第一天和最后一天

    這篇文章主要介紹了Vue 結合插件moment 實現獲取當前月的第一天和最后一天,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2023-10-10
  • vue使用ElementUI時導航欄默認展開功能的實現

    vue使用ElementUI時導航欄默認展開功能的實現

    這篇文章主要介紹了vue使用ElementUI時導航欄默認展開功能的實現,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-07-07

最新評論

汪清县| 兴安县| 泰和县| 乌拉特中旗| 金湖县| 航空| 林甸县| 永城市| 合山市| 漯河市| 靖州| 沈丘县| 钟山县| 新干县| 广德县| 枣阳市| 南部县| 修文县| 报价| 广州市| 那坡县| 德清县| 蓬溪县| 鲁山县| 容城县| 沾化县| 新余市| 静宁县| 房产| 江山市| 文成县| 彭阳县| 华亭县| 富宁县| 张家川| 太仆寺旗| 彭州市| 邮箱| 凤台县| 滨海县| 密山市|