-
@observable
* 概念: 创建一个被监听的对象, 没有@observable声明的视图不能检测到变化,把数据源变成可观测的,数据实现相应
ES6的装饰器在react中有时不支持,要安装插件
(1)写法一:
数组、对象、ES6中的map等都可以变成可观察的。
例:写一个可观测的数组:const arr = observable (['a','b'])
数值不可观察。
如果想让数值变成可观察的,使用box()或get()、set()
cosnt num = observable.box(9)
num.value = 10
observable和autorun
import { observable, autorun } from 'mobx';
const value = observable(0);
const number = observable(100);
autorun(() => {
console.log(value.get());
});
value.set(1);
value.set(2);
number.set(101);
可以看到,控制台中依次输出0,1,2。
observable可以用来观测一个数据,这个数据可以数字、字符串、数组、对象等类型(相关知识点具体会在后文中详述),而当观测到的数据发生变化的时候,如果变化的值处在autorun中,那么autorun就会自动执行。
上例中的autorun函数中,只对value值进行了操作,而并没有number值的什么事儿,所以number.set(101)
这步并不会触发autorun,只有value的变化才触发了autorun。
- autorun
* 概念: 初始执行一次, 当依赖的值有变化时候就会执行里面的函数, 此方法在mobx-react中被 @observer 所替代
(2)写法二:必须要写在类中
@observable const arr = ['a','b']
import {observable} from "mobx" //可观察的
export default()=>{
const arr = observable(["a","b"]) //响应式
const obj = observable({x:0,y:1})
console.log(arr) //打印结果如下
console.log(obj) //打印结果如下图2.
console.log(Array.isArray(arr)) //打印true,证明还是数组。
return null
}
- @computed
* 概念: 类比vue的Computed, 当依赖的值有变化时会执行一遍,有返回值
假如现在我们一个数字,但我们对它的值不感兴趣,而只关心这个数组是否为正数。这个时候我们就可以用到computed这个属性了。
const number = observable(10);
const plus = computed(() => number.get() > 0);
autorun(() => {
console.log(plus.get());
});
number.set(-19);
number.set(-1);
number.set(1);
依次输出了true,false,true。
第一个true是number初始化值的时候,10>0为true没有问题。
第二个false将number改变为-19,输出false,也没有问题。
但是当-19改变为-1的时候,虽然number变了,但是number的改变实际上并没有改变plus的值,所以没有其它地方收到通知,因此也就并没有输出任何值。
直到number重新变为1时才输出true。
实际项目中,computed会被广泛使用到。
const price = observable(199);
const number = observable(15);
//computed的其它简单例子
const allPrice = computed(() => price.get() * number.get());
顺便一提,computed属性和React Native中的ListView搭配使用很愉快。
- @action
mobx推荐将修改被观测变量的行为放在action中。action只能影响正在运行的函数,而无法影响当前函数调用的异步操作
* 概念: 改变store的值的行为
来看看以下例子:
import {observable, action} from 'mobx';
class Store {
@observable number = 0;
@action add = () => {
this.number++;
}
}
const newStore = new Store();
newStore.add();
以上例子使用了ES7的decorator,在实际开发中非常建议用上它,它可以给你带来更多的便捷
好了回到我们的例子,这个类中有一个add函数,用来将number的值加1,也就是修改了被观测的变量,根据规范,我们要在这里使用action来修饰这个add函数。
勇于动手的你也许会发现,就算我把@action去掉,程序还是可以运行呀。
class Store {
@observable number = 0;
add = () => {
this.number++;
}
}
这是因为现在我们使用的Mobx的非严格模式,如果在严格模式下,就会报错了。
接下来让我们来启用严格模式
import {observable, action, useStrict} from 'mobx';
useStrict(true);
class Store {
@observable number = 0;
@action add = () => {
this.number++;
}
}
const newStore = new Store();
newStore.add();
嗯,Mobx里启用严格模式的函数就是useStrict,注意和原生JS的"use strict"不是一个东西。
现在再去掉@action就会报错了。
可以使用runInAction这个API来解决之前的问题。
import {observable, action, useStrict, runInAction} from 'mobx';
useStrict(true);
class Store {
@observable name = '';
@action load = async () => {
const data = await getData();
runInAction(() => {
this.name = data.name;
});
}
}
你可以把runInAction有点类似action(fn)()的语法糖,调用后,这个action方法会立刻执行。
- extendObservable
* 概念: 初始为被 @observable设置为被监听值的, 可以通过extendObservable添加
否则自行添加的没办法被mobx检测到变化