很早以前看到的一篇關於mobx的文章,以前記得是有人翻譯過的,可是怎麼找都找不到,故花了點時間經過本身那半桶水的英文水平,加上Google翻譯一下,對於初學者,以及mobx的開發者提供些許幫助。javascript
這裏針對已經瞭解mobx,且有過一些簡單的開發的同窗,其中對文章有一些刪減,還有翻譯的不對的地方歡迎你們指出。java
MobX提供了一種簡單而強大的方法來管理客戶端狀態。 它使用一種稱爲(TFRP-Transparent Functional Reactive Programming
)的技術,其中若是任何相關值發生變化,它會自動計算派生值。 也就是經過設置跟蹤值更改的依賴關係圖來完成的。redux
MobX致使思惟方式的轉變(For the better
),並改變您的心理模型圍繞管理客戶端狀態。segmentfault
當咱們使用Mobx時,創建客戶端狀態模型是第一步, 這是最有可能被客戶端上呈現你的域模型的直接體現。實際上客戶端狀態也就是咱們一般說的Store
,瞭解redux的對此都很熟悉,雖然你只有一個Store,可是它是由多個子Store組件的,每個子Store用來處理應用程序的各類功能。數組
最簡單的入門方法是註釋Store的屬性,這些屬性將隨着@observable
而不斷變化。 請注意,我使用的是裝飾器語法,但使用簡單的ES5函數包裝器能夠實現相同的功能。函數
import { observable } from 'mobx' class MyStore { @observable name @observable description @observable author @observable photos = [] }
經過將對象標記爲@observable
,您將自動觀察其全部嵌套屬性。 如今這多是你想要的東西,但不少時候它更能限制可觀察性。 你可使用一些MobX修飾符來作到這一點:性能
asReference
當某些屬性永遠不會改變值時,這是很是有用的。 請注意,若是您確實更改了引用自己,它將觸發更改。ui
let address = new Address(); let contact = observable({ person: new Person(), address: asReference(address) }); address.city = 'New York'; // 不會觸發通知任何 // 將觸發通知,由於這是屬性引用更改 contact.address = new Address();
在上面的示例中,address屬性將不可觀察。 若是您更改地址詳細信息,則不會收到通知。 可是,若是您更改地址引用自己,您將收到通知。this
一個有趣的消息是一個可觀察對象的屬性,其值具備原型(類實例)將自動使用asReference()
註釋。 此外,這些屬性不會被進一步遞歸。
spa
asFlat
這比asReference
略寬一些。 asFlat
容許屬性自己可觀察,但不容許其任何子節點。 典型用法適用於您只想觀察數組實例而不是其項目的數組。 請注意,對於數組,length屬性仍然是可觀察的,由於它在數組實例上。 可是,對子屬性的任何更改都不會被觀察到。
首先建立@observable
全部內容,而後應用asReference
和asFlat
修飾符來修剪可觀察屬性。
當你深刻實現應用程序的各類功能時,你會發現這種修剪的好處。且當你開始時可能並不明顯,這徹底很正常。當你識別出不須要深度可觀察性的屬性時,請確保從新檢查你的Store
, 它能夠對您的應用程序的性能產生積極影響。
import {observable} from 'mobx'; class AlbumStore { @observable name; // 這裏不須要觀察 @observable createdDate = asReference(new Date()); @observable description; @observable author; // 只觀察照片數組,而不是單獨的照片 @observable photos = asFlat([]); }
和修剪可觀察屬性相反,你能夠擴展對象上可觀察性的範圍/行爲,而不是刪除可觀察性。 這裏有三個能夠控制它的修飾符:
asStructure
這會修改將新值分配給observable
時完成相等性檢查的方式。 默認狀況下,僅將引用更改視爲更改。 若是您但願基於內部結構進行比較,則可使用此修飾符。 這主要是針對值類型(也稱爲結構),只有在它們的值匹配時才相等。以下圖:
const { asStructure, observable } = require('mobx'); let address1 = { zip: 12345, city: 'New York' }; let address2 = { zip: 12345, city: 'New York' }; let contact = { address: observable(address1) }; // 將被視爲一種變化,由於它是一個新的引用 contact.address = address2; // 使用 asStructure() 修飾 let contact2 = { address: observable(asStructure(address1)) }; // 不會被視爲一種變化,由於它具備相同的價值 contact.address = address2;
asMap
默認狀況下,將對象標記爲可觀察對象時,它只能跟蹤最初在對象上定義的屬性。 若是添加新屬性,則不會跟蹤這些屬性。 使用asMap
,您甚至可使新添加的屬性可觀察。 在內部,MobX將建立一個相似ES6的Map,它具備與原生Map相似的API。
除了使用此修飾符,您還能夠經過從常規可觀察對象開始來實現相似的效果。 而後,您可使用extendObservable()
API添加更多可觀察的屬性。 當您想要延遲添加可觀察屬性時,此API很是有用。
computed
這是一個如此強大的概念,其重要性沒法獲得足夠的重視。 計算屬性不是域的真實屬性,而是使用實際屬性派生(也稱爲計算)。 一個典型的例子是person實例的fullName屬性。 它派生自firstName和lastName屬性。 經過建立簡單的計算屬性,您能夠簡化域邏輯。 例如,您能夠只建立一個計算的hasLastName屬性,而不是檢查一我的是否在任何地方都有lastName
class Person { @observable firstName; @observable lastName; @computed get fullName() { return `${this.firstName}, ${this.lastName}`; } @computed get hasLastName() { return !!this.lastName; } }
構建可觀察樹是使用MobX的一個重要方面,這使MobX開始跟蹤您的store
中有趣且值得改變的部分!
特此聲明: 在新版本4.0以上,asFlat
、asStructure
、asReference
以及asMap
等其餘API已經被棄用,具體事宜需參閱更新文檔。