jd-smart-fe / shared

共享文档
MIT License
25 stars 4 forks source link

MobX #13

Open ycshill opened 5 years ago

ycshill commented 5 years ago

背景

在 2013 年以前,对于数据流的控制一直以来是使用的 MVC(Model-View-Controller) 架构模式来进行数据的管理:

但是对于非常巨大的代码库和庞大的组织来说,MVC 很快就会变得非常复杂。每当工程师需要新增一个功能的时候,对代码的修改可能带来新的 bug,不同模块之间的依赖关系会变得“脆弱而且不可预测”。如图2:

现实的MVC图2 - 现实的MVC

基于以上的情况,Facebook 公司推出了 Flux 框架,用来管理数据,相比于 MVC ,它是一种更严格的数据流控制。

Flux 框架图3 - Flux框架

一个 Flux 包含四个部分,如下:

当用户请求一个动作,会触发 Action,之后 Action e驱动 Dispatcher 来进行分发 Action 操作,从而更新 Store 中的数据,Store 中数据改变后,就会更新 View 的展示。 Flux 虽然很好,也有不足之处,比如说 难以进行服务端渲染Store 混杂了逻辑和状态等,但是这种 单一数据流 的理念衍生出了像 Redux 和 MobX 框架的实现。本篇文章着重讲述 MobX。

简介

MobX 通过 响应式编程(在命令式编程环境中,a := b + c 表示将表达式的结果赋给 a,而之后改变 b 或者 c 的值不会影响 a 的值,但在响应式编程中, a 的值会随着 b 或 c 的值得改变而改变)的思想来管理数据。MobX 也是支持单向数据流的,是通过 action 触发 state 的变化,进而触发 state 的衍生对象(Computed 和 Reactions)。所有的衍生默认都是同步更新的。

MobX 实现图4 - MobX实现

概念

装饰器

ESNext 中新增了 decorator 属性,所谓装饰器,可以简单的理解为 锦上添花;以钢铁侠为例,钢铁侠本质上是一个人,只是装饰了很多的武器以后才变得很 NB ,不过怎么装饰他还是一个人。

钢铁侠 实现图5 - 钢铁侠装饰器

function decorateArmour(target, key, descriptor) {
  const method = descriptor.value;
  let moreDef = 100;
  let ret;
  descriptor.value = (...args)=>{
    args[0] += moreDef;
    ret = method.apply(target, args);
    return ret;
  }
  return descriptor;
}

class Man{
  constructor(def = 2,atk = 3,hp = 3){
    this.init(def,atk,hp);
  }

  @decorateArmour   //这个就是使用了装饰器
  init(def,atk,hp){
    this.def = def; // 防御值
    this.atk = atk;  // 攻击力
    this.hp = hp;  // 血量
  }
  toString(){
    return `防御力:${this.def},攻击力:${this.atk},血量:${this.hp}`;
  }
}

var tony = new Man();

console.log(`当前状态 ===> ${tony}`);
// 输出:当前状态 ===> 防御力:102,攻击力:3,血量:3

tips: ES7 中的 decorator 其实是一个语法糖,不过依赖于 Object.defineProperty(obj, prop, descriptor)

可观察数据

在 MobX 中, State 就对应业务的原始状态,可以通过 observable 或者 @observable 将这些状态变为可观察的,顾名思义,可观察数据就是 当数据变化的时候,可以被观察到

手写一个 todoList

开发环境的搭建

MobX 中大量的使用了 ES.Next 中的装饰器语法,为了在新搭建的项目中支持这种语法,有两种实现方式:

  1. 使用create-react-app project-name --scripts-version custome-react-scripts 创建项目,这种方式创建的项目,支持 修饰器语法LessSass

  2. 仍然使用create-react-app project-name 创建项目,然后执行yarn run eject弹射出配置文件,然后安装 yarn add babel-plugin-transform-decorators-legacy -D 修改 webpack 的配置文件,添加

    "babel": {
        "plugins": [
            "transform-decorators-legacy"
        ],
        "presets": [
            "react-app"
        ]
    }

    以上的内容配置好了以后,还要通过 yarn add mobx-react mobx -S 安装 mobx-react;

目录结构

目录结构图6-目录结构

代码

因为代码比较多,所以直接上github的地址:https://github.com/ycshill/shared/tree/master/mobx-share

MobX 常用工具函数和调试

此处输入图片的描述图8- redux&mobx

JiamaZhao commented 5 years ago

请教,action包装的作用是什么呢,官方为什么推荐改变observable变量的操作放在action里面