Vue的雙向綁定v-model

繼續(xù)理解vue的雙向綁定

首先,雙向綁定的作用是,為了達(dá)到view --> model / model --> view 從而達(dá)到mvvm,為了實(shí)現(xiàn)這個效果,應(yīng)分為以下三步進(jìn)行操作。

  1. v-model,{{...}},實(shí)現(xiàn)輸入框與文本節(jié)點(diǎn)與data的綁定
  2. view --> model ,input輸入框改變時,改變數(shù)據(jù)模型(v-text或{{}})中的數(shù)據(jù)
  3. model --> view , 數(shù)據(jù)模型中的數(shù)據(jù),因?yàn)楦鞣N操作而改變時,input中的值需要自動改變

1,使用文檔片段來處理節(jié)點(diǎn),將掛載的目標(biāo)子節(jié)點(diǎn)劫持之后再返回到視圖中

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

2,利用訪問器屬性,實(shí)現(xiàn)view改變,改變model

利用訪問器屬性的set監(jiān)聽,當(dāng)view發(fā)生改變時,將data中的text劫持為vm的訪問器屬性(因?yàn)樵L問器屬性會被優(yōu)先訪問,與其同名的屬性會被忽略,所以謂之劫持)
Object.defineProperty(obj,"a",{
      get:function(){},
      set:function(newVal){
            //更新node text屬性的值
      }
})
當(dāng)我們在輸入框輸入數(shù)據(jù)的時候,首先觸發(fā)input事件(或者keyup、change事件),在相應(yīng)的事件處理程序中,我們獲取輸入框的value并賦值給vm實(shí)例的text屬性。我們會利用defineProperty將data中的text劫持為vm的訪問器屬性,因此給vm.text賦值,就會觸發(fā)set方法。在set方法中主要做兩件事,第一是更新屬性的值,第二留到任務(wù)三再說。

3,發(fā)布 - 訂閱者模式

需要監(jiān)聽當(dāng)model中的data發(fā)送改變時,改變view。首先,這里的訂閱者是v-text和v-model或{{}}等等,每當(dāng)vm中返回一個新的data,則為此data添加一個dep主題對象,當(dāng)有指令綁定了此data則生成一個watcher(暫時不添加到Dep),當(dāng)set(作為發(fā)布者),被觸發(fā)之后,通知訂閱者watcher,執(zhí)行相應(yīng)操作。watcher做了以下事情
  1. 將自己賦給了一個全局變量Dep.target
  2. 進(jìn)而觸發(fā)了watcher自身的get方法,自身get方法獲取了對應(yīng)屬性的值,從而觸發(fā)了對應(yīng)屬性的get方法
  3. 對應(yīng)屬性的get方法檢測到全局Dep屬性非空后,將該watcher添加到該data的dep主題對象中,然后返回了屬性的值到watcher.value中
  4. 再然后wather的get方法繼續(xù)執(zhí)行下一步,將this.value賦值給this.node.nodeValue,從而更新視圖。
  5. 最后,將全局變量Dep.target設(shè)為null,Dep.target作為watcher和主題對象dep間溝通的唯一橋梁,使用完后要保持為空。

給尤大大打call...


再次理解Vue的雙向綁定v-model和{{ }}

1,首先,由view --> model的改變很好監(jiān)聽,因?yàn)橛衏hange這種事件的監(jiān)聽,每當(dāng)input數(shù)據(jù)變化之后,就動態(tài)改變el綁定的data的數(shù)據(jù)。

2,重點(diǎn),在vue實(shí)例中,每次出現(xiàn)一個新的data對象

第一步,設(shè)置發(fā)布者,利用Object.defineProperty監(jiān)聽對對象屬性的變化,但此時我們做的只是監(jiān)聽了這個值的變化,真正的Watch訂閱者還沒有添加。
第二步,解析文檔模型,每次遇到v-model或者{{}}就新建一個watcher實(shí)例,并給他傳入update的更新函數(shù),只要執(zhí)行這個更新函數(shù),視圖就會響應(yīng)地發(fā)生改變。
第三步,每次new一個watcher,wathcer將自身緩存在dep.target中,watcher會強(qiáng)行觸發(fā)發(fā)布者的getter函數(shù),getter函數(shù)判斷dep.target非空后,將watcher添加到Dep中間件的sub數(shù)組中去,然后將dep.target設(shè)置為空,此時每個需要設(shè)置watcher的文檔節(jié)點(diǎn)都設(shè)置好了。
第四步,每次data發(fā)生改變時觸發(fā)setter方法,改變屬性值,并觸發(fā)響應(yīng)dep的wathcer的之前傳進(jìn)來的update函數(shù),通知對應(yīng)的訂閱者,所有的訂閱者update,更新視圖中的值。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容