mobx是什么
mobx是简单、可扩展的状态数据管理工具。基于响应式编程思想,核心为状态变化引起的副作用应该被自动触发。应用程序逻辑只需要修改状态数据即可,mobx会自动触发切缓存渲染UI等业务定义的副作用,无需人工干预。解耦UI渲染和数据业务逻辑
mobx和redux对比:开发难度低、开发代码量少、渲染性能好。
class和decorator
class具有继承、多态功能。实现Dog继承Animal
//es5实现继承的方式
function Animal(){}
function Dog(){}
Object.defineProperties(Animal.prototype, {
name: {
value(){
return 'Animal'
}
},
say: {
value(){
return `I am ${this.name()}`
}
}
});
//多态:子类覆盖父类的方法
Dog.prototype = Object.create(Animal.prototype, {
constructor: {
value: Dog,
enumerable: false
},
name: {
value(){
return "Dog"
}
}
});
dog instanceof Animal
dog.__proto__.__proto__... == Animal.prototype
dog.__proto__ == Dog.prototype
Dog.prototype.__proto__... === Animal.prototype
//es6中实现继承
class Animal{
name(){
return 'Animal';
}
say(){
return `I am ${this.name()}`
}
}
class Dog extends Animal{
foo='foo';
name(){
return 'Dog';
}
}
console.log(new Dog() instanceof Animal);
decorator是修饰器,在声明阶段实现类与类成员注解的一种语法
//类的decorator
function log(target){
const desc = Object.getOwnPropertyDescriptors(target.prototype);
for(let key of Object.keys(desc)){
if(key === 'constructor'){
continue;
}
const func = desc[key].value;
if (typeof func === 'function'){
Object.defineProperty(target.prototype, key, {
value(...args){
console.log('brefor ', key);
const res = func.apply(this, args);
console.log('after ', key);
return res;
}
})
}
}
}
//类属性的decorator
function readonly(target, key, descriptor){
descriptor.writable = false;
}
//类方法的decorator
function validate(target, key, descriptor){
const func = descriptor.value;
descriptor.value = function(...args){
for (let num of args) {
if(typeof num != 'number'){
throw new Error(`${num} is not number`);
}
}
return func.apply(this, args);
}
}
@log
class Numberis{
@readonly PI = 3.14;
@validate
sum(...args){
return args.reduce((s, c)=> s + c, 0);
}
}
//new Numberis().PI = 1000;
console.log(new Numberis().sum(23, 'xxx'));
mobx 常用API
- 1、可观察的数据(observable)
observable是一种让数据的变化可以被观察的方法。原始数据类型:string、number、boolean、symbol。复杂数据类型:对象、数组、map
import { observable, isArrayLike,isObservableObject, extendObservable} from 'mobx';
//observable Proxy、ObservableMap
const arr = observable([1,2,3]);
const obj = observable({a: 'a'});
const map = observable(new Map());
//observable.box ObservableValue类型
const num = observable.box(1);
const str = observable.box('aaa');
const bool = observable.box(true);
//获取原始值通过get,修改原始值set
console.log(num.get(), str, bool.get())
//封装后直接使用@observable就可以修饰不同类型的值
class Store {
@observable array = [1,2,3];
@observable object = {a: 'aaa'};
@observable map = new Map();
@observable num = 122;
@observable str = 'aaaa';
@observable bool = false;
}
- 2、对可观察对象作出反应,监听变量的更改
常用API有computed、autorun、when、reaction
import { observable, computed, autorun, when, reaction, action, runInAction } from 'mobx';
class Store {
@observable array = [1,2,3];
@observable object = {a: 'aaa'};
@observable map = new Map();
@observable num = 122;
@observable str = 'aaaa';
@observable bool = false;
@computed get mixed(){
return store.str + '/' + store.num;
}
}
const store = new Store();
//computed 将可观察数据组合起来变成一个新的可观察数据
const foo = computed(function(){
return store.str + '/' + store.num;
});
foo.get();
foo.observe(function(change){
console.log(change);
});
//autorun 修改可观察数据就会执行,如下为str、num
autorun(function(){
console.log(store.mixed);
})
//when 第一个参数必须根据可观察数据返回boolean值,为真执行第二个函数
when(()=> {
return store.bool;
}, ()=> {
console.log('this is true');
})
//reaction 应用场景:在没有数据之前不想,也没有必要调用写缓存的逻辑
reaction(()=> [store.num, store.str], (arr)=> {
console.log(arr);
})
- 3、修改可观察数据action
数据的赋值每次都会触发autorun、reaction,这样会带来严重的浪费。多数情况下,同步修改n个变量,只希望变更一次视图。所以引入action,多次对状态的赋值合并成一次,从而减少触发autorun、reaction的次数
class Store{
...
@action
bar(){
this.num = 4343;
this.str = 'bbbb';
}
@action.bound
foo(){
this.num = 4343;
this.str = 'bbbb';
}
}
const store = new Store();
//action
store.bar();
//action.bound
var foo = store.foo;
foo();
//runInAction
runInAction('modify', ()=>{
store.num = 4343;
store.str = 'bbbb';
})
mobx的应用
mobx-react是mobx和react之间的桥梁,将react组件转换成对可观察数据的反应,准确的讲是将react的render方法包装成autorun
利用mobx-react工具库让mobx维护react项目状态。解耦业务逻辑和视图渲染
- 1、将react中的用户行为转换成action
- 2、将数据绑定到react组件上以驱动视图
mobx常用工具函数
observe、toJS、trace、spy
- 尽可能晚的取出可观察数据的值
- 尽可能细的拆分视图组件
- 使用专用组件处理列表
参考链接
- 学习代码Github地址:mobx应用--实现TodoList
- mobx入门基础教程
- mobx官网地址