前言
不久前天看到一個比較有趣的問題,vue中data改變後,如何讓檢視同步更新,搜尋了一下,並沒有發現解決問題的方法,只能從原始碼去找解決方法了。
原因
我們都知道,在vue
中改變資料後,檢視並不是同步更新的。
在vue例項初始化後,會將data設定為響應式物件,當我們執行this.xxx = 1
時,會觸發這個響應式物件的setter。在setter中,會觸發更新,通知所有訂閱了xxx
的訂閱者。但是這個觸發更新並不是同步的,它會將所有的watcher
都新增到一個佇列,並在nextTick
之後去更新檢視。
這就是vue不能同步更新檢視的原因。
解決方法
知道了原因,總能找到解決方法。
既然是在nextTick
的時候去更新檢視,這個時候,必然會去執行一個更新檢視的方法,那麼我們手動在資料改變的時候去執行這個方法,就達到了同步更新檢視的目的。
在瞭解原始碼後,我們可以發現執行的是watcher.run()
這個方法,那麼問題來了,怎麼去獲取這個方法?
想快速瞭解這一塊建議閱讀 Vue.js技術揭祕
我們在控制檯列印一下this
可以在_watcher
這個物件的原型上找到run
這個方法,因此問題就解決了。
this.xxx = 1;
this._watcher.run()
複製程式碼
執行以上程式碼,在更新完資料後,手動更新檢視,就可以做到同步的效果。
更好的解決方法
如果每次想要檢視同步更新都要加一句 this._watcher.run()
,那豈不是太麻煩了,因此,我寫了一個外掛,支援this.xxx = 1
之後就同步更新檢視。
這個外掛原理很簡單,就是在元件的options
裡邊加了一個選項syncData
,跟data
是類似的,然後放入data
裡面,created
鉤子呼叫的時候重新劫持這部分資料,syncData
裡邊資料改變的時候,自動觸發_watch.run()
,從而同步更新檢視。
外掛地址:GitHub地址
後記
講道理我覺得這個外掛並沒有什麼卵用,理論上這個外掛能解決的問題$nextTick
都可以解決。