MobX 中文文档

  开始纠错

如何使用装饰器

使用ES.next的语法是可选的。这一部分解释了如何去使用它们,或者如果避免使用它们。

使用装饰器的优势:

  • 声明式语法,最小代码量。
  • 便于使用和阅读,大多数MobX用户都这么用。

使用装饰器的缺点:

  • 这是Stage-2 ES.next的特性,兼容性上可能存在问题。
  • 需要一些安装和编译过程,目前只支持Babel/Typescript两种预编译器

使用装饰器

如果你想使用装饰器可以按照以下步骤

TypeScript

使 tsconfig.json 文件中的 experimentalDecorators 选项变为启用,或者以flag --experimentalDecorators 的形式传给编译器

Babel:

安装:npm i --save-dev babel-plugin-transform-decorators-legacy, 并且在你的 .babelrc 配置文件中开启。

{
  "presets": [
    "es2015",
    "stage-1"
  ],
  "plugins": ["transform-decorators-legacy"]
}

注意插件的顺序非常重要:transform-decorators-legacy 应该放在插件的第一个。关于Babel还有什么问题的话,请先查看这个issue

当使用react native的时候,下面这个预设可以代替 transform-decorators-legacy

{
  "presets": ["stage-2", "react-native-stage-0/decorator-support"]
}

装饰器的限制

不使用装饰器也可以创建一个可观察的对象。

如果不使用装饰器,extendObservable 可以用于将一个可观察的属性引入对象,一个典型的例子就是构造器所做的。 下面这个例子介绍了如何在构造器函数中定义可观察属性、计算值和行为

function Timer() {
    extendObservable(this, {
        start: Date.now(),
        current: Date.now(),
        get elapsedTime() {
            return (this.current - this.start) + "seconds"
        },
        tick: action(function() {
              this.current = Date.now()
        })
    })
}

或者,使用类声明的方式:

class Timer {
    constructor() {
        extendObservable(this, {
            /* 查看之前的列表 */
        })
    }
}

使用装饰器创建可观察属性。

装饰器和Class一起使用是非常爽的。 当使用装饰器时,可观察变量、计算值、行为都能很简单地定义。

class Timer {
    @observable start = Date.now();
    @observable current = Date.now();

    @computed get elapsedTime() {
        return (this.current - this.start) + "seconds"
    }

    @action tick() {
        this.current = Date.now()
    }
}

创建观察者组件

来自于MobX-package这个包的 observer 函数或装饰器可以将React组件转换为观察者组件。 你所需要记住的是:@observer class ComponentName {} 只是 const ComponentName = observer(class { }) 的语法糖。 下面这些形式创建的观察者组件都是可行的:

无状态组件,ES5:

const Timer = observer(function(props) {
    return React.createElement("div", {}, props.timer.elapsedTime)
})

无状态组件, ES6:

const Timer = observer(({ timer }) =>
    <div>{ timer.elapsedTime }</div>
)

React 组件, ES5:

const Timer = observer(React.createClass({
    /* ... */
}))

React 组件 class, ES6:

const Timer = observer(class Timer extends React.Component {
    /* ... */
})

React 组件类和装饰器一起使用, ES.next:

@observer
class Timer extends React.Component {
    /* ... */
}