一、[前导]class类语义
用原型链实现继承:
function Animal(){} //父类
function Dog(){} //子类
/**根据原型链
dog._proto_ === Animal.prototype
Dog.proptotype._proto_ === Animal.prototype
**/
//--->实现继承(但是Dog.prototype.constructor指向的是Animal)
Dog.prototype = Object.create(Animal.prototype);
//父类Animal定义两个方法name,say
Object.defineProperties(Animal.prototype,{
name:{
value() {
return 'Animal';
}
}
say:{
value() {
return 'i am ${this.name()}';
}
}
});
//在子类Dog中重新定义name方法(多态实现)
Dog.prototype = Object.create(Animal.prototype, {
//让子类的constructor强制指向自己
constructors:{
value: Dog,
enumerable: false
}
name:{
value() {
return 'Dog';
}
}
});
class类的继承:
class Animal {
name() {
return 'Animal';
}
}
class Dog extends Animal {
name() {
return 'Dog';
}
}
console.log(new Dog() instanceof Animal); //true
二、【前导】修饰器: decorator
修饰类方法
/*
log修饰器,target指被修饰的类对象calNumber
*/
function log(target){
}
/*
** @ 是decorate的语法 --意为修饰
*/
@log
class calNumber {
}
修饰类成员
/*
reanderOnly 修饰器
**target指被修饰的成员对象 data
**key 对象名称
**descriptor
*/
function reanderOnly(target, key, descriptor ){
descriptor.writable = false; //不可改
}
class calNumber {
@reanderOnly data = '888';
}
三、mobx--observable
[1] observable 数组: 将数组转变为可观察的,数组中的所有包括未来的值都是可观察的。
[2] observable.box --对于原始类型:number , string , Boolean,包装成可观察的数据.
每个对象都有Get方法,可以得到原始类型值,set方法可以去设置更新原始类型值。
import {observable} from "mobx";
const cityName = observable.box("Vienna");
console.log(cityName.get());
// 输出 'Vienna'
cityName.observe(function(change) {
console.log(change.oldValue, "->", change.newValue);
});
cityName.set("Amsterdam");
// 输出 'Vienna -> Amsterdam'
API简化 ,在class类定义中,可以直接使用decorate的语法:比如
@observable str = "hello";
@observable arr = [1,2,3,4,5];
@observable num = 88;
四.computed 、autorun
computed:纯函数,返回一个值。
autorun:在可观察数据被修改后,自动去执行依赖的数据的函数。
import {observable, computed , autorun} from 'mobx'
class Store {
@observable title:string = "hello mobx";
@observable age:number = 44;
@computed get calculate() {
return this.age < 88 ? '中年人' : '老年人';
}
}
var store = new Store();
autorun(() => {
console.log(store.calculate); //'中年人'
}, {
onError(e) {
window.alert("onError");
}
})
五、when、reaction
when
when(predicate: () => boolean, effect?: () => void, options?)
when
观察并运行给定的 predicate
,直到返回true。 一旦返回 true,给定的 effect
就会被执行,然后 autorunner(自动运行程序) 会被清理。 该函数返回一个清理器以提前取消自动运行程序。
when接收两个参数,第一个参数返回true,第二个参数就会执行。
- 如果第一个参数一开始就返回真,那么第二个参数会同步执行。
- 第一个参数必须是根据可观察的数据来计算boolean返回值,不能是普通变量。
class Store {
@observable title:string = "hello mobx";
@observable age:number = 44;
@observable isVisible:boolean = false;
}
var store = new Store();
when(() =>store.isVisible , ()=> console.log("it is true!"));
store.isVisible = true;
// Log: it is true!
reaction
reaction接收两个参数,第一个参数返回的值,作为第二个函数的参数
应用场景:第一次数据拿到后,可加入缓存。
class Store {
@observable title:string = "hello mobx";
@observable age:number = 44;
@observable isVisible:boolean = false;
}
var store = new Store();
reaction(() =>[store.title , store.age ], (arr:any[]) => console.log(arr));
//改变被观察的数据的值
store.title = "we are";
store.age = 32;
// Log: ["we are" , 32]
六、action: 改变观察的数据
action是任何用来修改状态的东西。将多次对可观察数据的状态的赋值合并成一次,达到减少触发autorun 和reaction的次数。
class Store {
@observable title:string = "hello mobx";
@observable age:number = 44;
@observable isVisible:boolean = false;
@action bar() {
store.title = "we are";
store.age = 32;
}
}
var store = new Store();
reaction(() =>[store.title , store.age ], (arr:any[]) => console.log(arr));
//调用bar这个action
store.bar();
// Log: ["we are" , 32]
action.bound
action
装饰器/函数遵循 javascript 中标准的绑定规则。 但是,action.bound
可以用来自动地将动作绑定到目标对象。 注意,与 action
不同的是,(@)action.bound
不需要一个name参数,名称将始终基于动作绑定的属性。
class Store {
@observable title:string = "hello mobx";
@observable age:number = 44;
@observable isVisible:boolean = false;
@action.bound bar() {
store.title = "we are";
store.age = 32;
}
}
var store = new Store();
reaction(() =>[store.title , store.age ], (arr:any[]) => console.log(arr));
//调用bar这个action
var bar = store.bar;
bar();
// Log: ["we are" , 32]
class Store {
@observable title:string = "hello mobx";
@observable age:number = 44;
@observable isVisible:boolean = false;
@observable list: number[] = [1,2,3,4];
//删除list中最后一项
@action.bound cancel() {
console.log("@action.bound",this);
}
@action test() {
console.log("@action",this);
}
}
const store = new Store();
store.cancel();
store.test();
runInAction(name?, thunk)
runInAction(f)
是 action(f)()
的语法糖。可以用于匿名的action:
var store = new Store();
reaction(() =>[store.title , store.age ], (arr:any[]) => console.log(arr));
runInAction(() =>{
store.title = "we are";
store.age = 32;
})
// Log: ["we are" , 32]
mobx-react的应用
【1】
【2】mobx v6.0以上
1.mobx/store.js
2.mobx/index.js
3.src/index.tsx
4.父组件 Box/BarBox.tsx
5.子组件 cube,tsx
效果