深入Vue的響應式原理

來源:互聯網
上載者:User

標籤:轉換   也有   ima   不必要   mis   this   嵌套   對象   一個   

工作的過程中,有時候會有資料改變但是視圖沒有更新的問題,作者在vue的官方文檔中有提到這個問題,我來總結一下

1.vue的每個組件執行個體都有對象的watcher執行個體對象,它會在組件渲染的過程中把屬性記錄為依賴,當依賴項的setter方法被調用,會通知watcher對象重新計算,從而使它關聯的組件更新

檢測變化的注意項,vue不能檢測到對象屬性的添加或者刪除,由於 Vue 會在初始化執行個體時對屬性執行 getter/setter 轉化過程,所以屬性必須在 data 對象上存在才能讓 Vue 轉換它,這樣才能讓它是響應的

2.Vue 不允許在已經建立的執行個體上動態添加新的根級響應式屬性 (root-level reactive property)。然而它可以使用 Vue.set(object, key, value) 方法將響應屬性添加到嵌套的對象上:

Vue.set(vm.someObject, ‘b‘, 2)// 或者this.$set(this.someObject,‘b‘,2)

有時你想向一個已有對象添加多個屬性,例如使用 Object.assign() 或 _.extend() 方法來添加屬性。但是,這樣添加到對象上的新屬性不會觸發更新。在這種情況下可以建立一個新的對象,讓它包含原對象的屬性和新的屬性:

// 代替 `Object.assign(this.someObject, { a: 1, b: 2 })`this.someObject =  Object.assign({}, this.someObject, {a: 1, b: 2 })

3.聲明響應式屬性

由於 Vue 不允許動態添加根級響應式屬性,所以你必須在初始化執行個體前聲明根級響應式屬性,哪怕只是一個空值:

var vm = new Vue({  data: {    // 聲明 message 為一個空值字串    message: ‘‘  },  template: ‘<div>{{ message }}</div>‘})// 之後設定 `message`vm.message = ‘Hello!‘

如果你未在 data 選項中聲明 messageVue 將警告你渲染函數正在試圖訪問的屬性不存在。

這樣的限制在背後是有其技術原因的,它消除了在依賴項跟蹤系統中的一類邊界情況,也使 Vue 執行個體在類型檢查系統的協助下啟動並執行更高效。而且在代碼可維護性方面也有一點重要的考慮:data 對象就像組件狀態的概要,提前聲明所有的響應式屬性,可以讓組件代碼在以後重新閱讀或其他開發人員閱讀時更易於被理解。

4.非同步更新隊列(重點理解)

Vue 非同步執行 DOM 更新。只要觀察到資料變化,Vue 將開啟一個隊列,並緩衝在同一事件迴圈中發生的所有資料改變。如果同一個 watcher 被多次觸發,只會被推入到隊列中一次。這種在緩衝時去除重複資料對於避免不必要的計算和 DOM 操作上非常重要。然後,在下一個的事件迴圈“tick”中,Vue 重新整理隊列並執行實際 (已去重的) 工作。Vue 在內部嘗試對非同步隊列使用原生的 Promise.then 和 MessageChannel,如果執行環境不支援,會採用 setTimeout(fn, 0) 代替

當你設定 vm.someData = ‘new value‘ ,該組件不會立即重新渲染。當重新整理隊列時,組件會在事件迴圈隊列清空時的下一個“tick”更新。多數情況我們不需要關心這個過程,但是如果你想在 DOM 狀態更新後做點什麼,這就可能會有些棘手。雖然 Vue.js 通常鼓勵開發人員沿著“資料驅動”的方式思考,避免直接接觸 DOM,但是有時我們確實要這麼做。為了在資料變化之後等待 Vue 完成更新 DOM ,可以在資料變化之後立即使用 Vue.nextTick(callback) 。這樣回呼函數在 DOM 更新完成後就會調用。例如:

var vm = new Vue({  el: ‘#example‘,  data: {    message: ‘123‘  }})vm.message = ‘new message‘ // 更改資料vm.$el.textContent === ‘new message‘ // falseVue.nextTick(function () {  vm.$el.textContent === ‘new message‘ // true})

 

深入Vue的響應式原理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.