装饰器

装饰器

MobX 有一组装饰器来定义 observable 属性的行为。

  • observable: observable.deep 的别名

装饰器可以使用 API decorateobservable.objectextendObservableobservable(创建对象时) 来指定对象成员的行为。 如果没有传入装饰器,默认为对任意键值对使用 observable.deep,对 getters 使用 computed

import {observable, autorun, action} from "mobx"; var person = observable{ name: "John", age: 42, showAge: false, get labelText() { return this.showAge ? `${this.name} (age: ${this.age})` : this.name; }, // 动作: setAge(age) { this.age = age; } }, { setAge: action // 其他属性默认为 observables / computed } Copy

class Person { name = "John" age = 42 showAge = false get labelText() { return this.showAge ? `${this.name} (age: ${this.age})` : this.name; } setAge(age) { this.age = age; } } // 使用 decorate 时,所有字段都应该指定 (毕竟,类里的非 observable 字段可能会更多) decorate(Person, { name: observable, age: observable, showAge: observable, labelText: computed, setAge: action }) Copy

深层可观察性

当 MobX 创建一个 observable 对象时,(使用 observableobservable.objectextendObservable),它引入的 observable 属性默认是使用 deep 调节器的。deep 调节器主要是为任何新分配的值递归调用 observable(newValue)。 会依次使用 deep 调节器...你可以想象。

这是一个非常便利的默认设置。无需额外的工作,分配给 observable 的所有值本身也将转变成 observable(除非它们已经是),因此不需要额外的工作就可使对象转变成深 observable 。

引用可观察性

然后在某些情况下,不需要将对象转变成 observable 。 典型案例就是不可变对象,或者不是由你管理,而是由外部库管理的对象。 例如 JSX 元素、DOM 元素、像 History、window 这样的原生对象,等等。 对于这类对象,只需要存储引用而不用把它们转变成 observable 。

对于这些情况,可以使用 ref 调节器。它会确保创建 observable 属性时,只追踪引用而不会把它的值转变成 observable 。 示例:

class Message { @observable message = "Hello world" // 虚构的例子,如果 author 是不可变的,我们只需要存储一个引用,不应该把它变成一个可变的 observable 对象 @observable.ref author = null } Copy

或者使用 ES5 语法:

function Message() { extendObservable{ message: "Hello world", author: null }, { author: observable.ref }) } Copy

注意,可以通过使用 const box = observable.shallowBox(value) 来创建一个装箱的 observable 引用

浅层可观察性

observable.shallow 调节器会应用“单层”可观察性。如果想创建一个 observable 引用的集合,那你会需要它。 如果新集合分配给具有此调节器的属性,那么它会转变成 observable,但它的值将保持原样,不同于 deep 的是它不会递归。 示例:

class AuthorStore { @observable.shallow authors = [] } Copy

在上面的示例中,使用普通的 author 数组分配给 authors 的话,会使用 observables 数组来更新 author,observables 数组包含原始的、非 observable 的 author 。

注意, { deep: false } 了作为选项传给 observableobservable.objectobservable.arrayobservable.mapextendObservable 来创建浅集合。