Vue雙向數據綁定

1、引入

  談及Vue中的數據雙向綁定,咱們天然而然的想到是經過v-model指令實現的。但具體是怎麼實現的呢?下面就介紹一下。javascript

 

2、v-model語法糖是什麼?原理是什麼?

  v-model語法糖是vue多個基礎語法(屬性綁定 和事件綁定)的簡寫。html

  原理:給表單元素input綁定經過"v-bind:"綁定value屬性的數據msg,再給表單元素input添加監聽value值改變的事件@input,給msg從新賦值。vue

  代碼:java

<!-- <input type="text" v-model="msg"> -->
<input :value="msg" type="text" @input="msg=$event.target.value">

 

3、雙向數據綁定的原理?

  vue中數據雙向綁定經過v-model實現,雙向綁定指的是視圖和內存中的數據進行雙向綁定。(經過Object.defineProperty和給元素註冊事件)node

  表單元素改變數據的原理:
算法

  • 實現數據驅動視圖
  1. 須要先定義一個data對象將其中msg屬性的值顯示到視圖中。想要經過Object.defineProperty來監測其值得變化是不可能實現的,由於使用他的同時須要給對象賦值並監聽,而data對象中已經有了這個屬性並綁定到了頁面中顯示,沒法再從新定義該屬性。這就須要新建一個空對象vm,經過給vm定義屬性並監測來實現這個功能。
  2. Object.defineProperty調用時的第三個參數爲對象配置項,其中的get()方法爲vm的msg屬性值被獲取時觸發的回調函數。set()方法爲vm的msg屬性值被設置時觸發的回調函數,set()函數的參數爲msg屬性的新值。
  • 實現視圖驅動數據

  經過給表單元素註冊input事件,將表單元素中的value值賦給vue.msg瀏覽器

 <!-- 1. 把數據渲染到表單元素中 -->
  <!-- 2. 當你修改數據的時候,表單元素的值發生改變,視圖須要更新 -->
  <!-- 3. 當你使用表單元素的時候,你在修改元素的值,對應的數據也要發生改變 -->
  <h5></h5>
  <input type="text">
  <script>
    // const vm = new Vue({data:{msg:'hi vue'}}) vm.msg = '數據'
    // 使用用定義能夠監聽(觀察)的屬性的。
    const vm = {}
    const data = { msg: 'hi vue' }
    // 獲取dom
    const h5 = document.querySelector('h5')
    const input = document.querySelector('input')
    // 1. 默認渲染
    h5.innerHTML = data.msg
    input.value = data.msg
    // 2.1 監聽 data中的msg的值改變  觀察 data中的msg的值改變  最終監聽的是vm的msg屬性變化
    // 2.2 若是 數據改變  修改視圖
    // 三個參數  給誰定義一個屬性  屬性的名稱  對象配置項(get 獲取屬性值 set 設置屬性值)
    Object.defineProperty(vm, 'msg', {
      get() {
        // 當獲取msg屬性值時觸發
        // console.log('get')
        return data['msg']
      },
      set(newValue) {
        // 當設置msg屬性值時觸發
        // console.log('set')
        // console.log(newValue)
        // 數據改變
        data['msg'] = newValue
        // 修改視圖
        h5.innerHTML = newValue
        input.value = newValue
      }
    })
    // 3. 監聽 表單元素 的值改變事件  修改數據便可(上面已經實現數據驅動視圖)
    input.oninput = function(){
      // console.log(this.value)
      vm.msg = this.value
    }
  </script>

  整體描述:dom

  • Vue內部會把data中的數據經過defineProperty方法轉化爲set和get的監控方式函數

  • 當data中的數據發生變化時,會觸發對應的set或者get性能

    • 修改屬性值的時候,觸發set方法

    • 訪問屬性值的時候,觸發get方法

  • 監控數據變化的目的仍是爲了更新頁面(僅僅更新數據變化對應的DOM節點:儘量少的更新DOM)

  • 可是完成上述要求須要底層虛擬DOM的支持

 

4、什麼是虛擬DOM?

  瀏覽器更新DOM比較耗時,爲了節省時間,須要儘量少的更新DOM。虛擬DOM是對真實DOM的一種描述;其組成部分虛擬節點也描述了真實的DOM節點,本質上就是普通對象

// VNODE 虛擬節點:描述了真實的DOM節點,本質上就是普通對象
{
    tagName: 'div'
    attrs: { class: "active", id: "info"}
    content: "hello"
}
  • 虛擬DOM也會造成一個樹狀結構,描述了真實的DOM樹(造成虛擬DOM樹和真實DOM樹的對應關係)

  • 若是數據發生變化,那麼就會觸發虛擬DOM數的對比(diff算法,過程發生在內存中)

  • 對比的結果是:有變化的虛擬節點的集合

  • 上述虛擬節點須要轉化爲真實的DOM節點(下面是虛擬下面是虛擬節點轉換爲真實節點的過程)

var div = document.createElement(vnode.tagName)
div.setAttibute(key, value)
div.innerHTML = vnode.content
  • 最終會把真實的節點更新到頁面

  雙向數據綁定運用虛擬DOM的進一步解釋說明:

    在使用defineProperty進行到set()時,會採用虛擬DOM來跟新視圖;虛擬DOM有新、舊兩份數據存儲在內存中,每次監測到數據改變時,計算機會經過diff算法對比兩份數據的區別,獲得有變化的虛擬節點的集合,並將它們轉換爲真實的DOM節點更新到頁面中。

    採用上面方式的緣由就是瀏覽器解析完整DOM樹的時間、性能消耗,要遠比內存對比數據再進行局部渲染的消耗大得多。內存處理數據的速度要比瀏覽器快的多。

相關文章
相關標籤/搜索