Vue.observable
實例:Vue.observablevue
<body> <div id="root"> {{message}} <button @click="change">Change</button> </div> <script> const state = Vue.observable({ message: 'Vue 2.6' }) const mutation = { setMessage(value) { state.message = value } } new Vue({ el: '#root', computed: { message() { return state.message } }, methods: { change() { mutation.setMessage('Vue 3.0') } } }) </script> </body>
官方解釋:react
Vue.observable(object) 是vue2.6版本新增的全局API,它能夠讓一個對象可響應。Vue 內部會用它來處理 data 函數返回的對象。
返回的對象能夠直接用於渲染函數和計算屬性內,而且會在發生改變時觸發相應的更新。也能夠做爲最小化的跨組件狀態存儲器,用於簡單的場景
git
在 Vue 2.x 中,被傳入的對象會直接被 Vue.observable 改變;在 Vue 3.x 中,則會返回一個可響應的代理,而對源對象直接進行修改仍然是不可響應的。所以,爲了向前兼容,官方推薦始終操做使用 Vue.observable 返回的對象,而不是傳入源對象。vuex
通俗來講,Vue.observable在簡單場景下能夠代替vuexapi
本示例中Vue.observable執行流程:數組
- 首先initGlobalAPI (vue.js:5406)
- 執行Vue.observable內容
// 2.6 explicit observable API Vue.observable = function (obj) { observe(obj); return obj };
- vue初始化
- 使用計算屬性將state.message渲染到頁面
- 點擊按鈕
- 執行change()
- 執行setMessage(),修改state.message的值
- 使用計算屬性將新的state.message值渲染到頁面
能夠看出Vue.observable實際就是封裝了observe:
markdown
- 首先判斷是否包含__ob__這個屬性
- 實例化一個Observer對象:
- 因爲本實例中傳入的不是數組,進入walk()
- 在walk中遍歷key,並使用defineReactive$$1建立響應式對象
Walk through all properties and convert them into getter/setters. This method should only be called when value type is Object.
遍歷全部屬性並將它們轉換爲getter/setter。僅當值類型爲Object時才應調用此方法。
ide
- 經過property.get進行取值,經過property.set進行賦值
- 接下來調用Object.defineProperty()給對象定義響應式屬性(Object.defineProperty是vue.js實現「響應式系統」的關鍵之一)
- enumerable,屬性是否可枚舉,默認 false。
- configurable,屬性是否能夠被修改或者刪除,默認 false。
- get,獲取屬性的方法。(進行依賴收集)(數據劫持)
- set,設置屬性的方法。(進行響應式更新)
- dep.notify():經過dep.notify()對觀察者watchers進行通知
- 而後state就成全局響應式對象了,
拓展:函數
- 深刻響應式原理 — Vue.js
- vue原理探索–響應式系統
- Vue setter/getter 是何原理?
- 深刻解析Vue依賴收集原理
- Vue 核心之數據劫持
- Vue源碼解讀之Dep,Observer和Watcher
思想來源:觀察者模式 vs 發佈訂閱模式