Mobx的使用

文章目录

1、Mobx简介

2、Mobx的使用

2.1、环境搭建

创建项目

mkdir mobxdemo
cd mobxdemo
npm init -y

安装依赖

cnpm i webpack webpack-cli -D
cnpm i html-webpack-plugin -D
cnpm i babel-loader @babel/core @babel/preset-env -D
cnpm i @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties -D
cnpm i @babel/plugin-transform-runtime -D
cnpm i @babel/runtime -S
cnpm i mobx -S

创建源文件

mkdir src
mkdir dist
mkdir public
创建 public/index.html
创建 src/index.js
创建 webpack.config.js

编写webpack.config.js

const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'development',
  entry: path.resolve(__dirname, 'src/index.js'),
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'main.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
            plugins: [
              //支持装饰器
              ["@babel/plugin-proposal-decorators", { "legacy": true }],
              ["@babel/plugin-proposal-class-properties", { "loose" : true }],
              ['@babel/plugin-transform-runtime']
            ]
          }
        }
      }
    ]
  },
  plugins:[
		new HtmlWebPackPlugin({
			template: 'public/index.html',
			filename: 'index.html',
			inject: true
		})
	]
}

编写index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>

</body>
</html>

在package.json中配置打包的命令:

{
    "scripts": {
        "build": "webpack --mode production"
    }
}

2.2、Mobx基础操作

在 src/index.js 中操作。

2.2.1、observable可观察的状态

(1)map

import {observable} from 'mobx'
// 声明
const map = observable.map({a: 1, b: 2});
// 设置
map.set('a', 11);
// 获取
console.log(map.get('a'));
console.log(map.get('b'));
// 删除
map.delete('a');
console.log(map.get('a'));
// 判断是否存在属性
console.log(map.has('a'));

(2)object

import {observable} from 'mobx'
// 声明
const obj = observable({a: 1, b: 2});
// 修改
obj.a = 11;
// 访问
console.log(obj.a, obj.b);

(3)array

import {observable} from 'mobx'
const arr = observable(['a', 'b', 'c', 'd']);
// 访问
console.log(arr[0], arr[10]);
// 操作
arr.pop();
arr.push('e');

基础类型

import {observable} from 'mobx'
const num = observable.box(10);
const str = observable.box('hello');
const bool = observable.box(true);
// 获得值
console.log(num.get(), str.get(), bool.get());
// 修改值
num.set(100);
str.set('hi');
bool.set(false);
console.log(num.get(), str.get(), bool.get());

2.2.2、 observable装饰器

import {observable} from 'mobx'// observable这个函数可以识别当成普通函数调用还是装饰器调用// 如果是装饰器,会自动识别数据类型,使用不同的包装转换方案。class Store{  @observable arr = [];  @observable obj = {a: 1};  @observable map = new Map();  @observable str = 'hello';  @observable num = 123;  @observable bool = false;}const store = new Store();console.log(store);console.log(store.obj.a);

注意:vscode编译器中,js文件使用装饰器会报红。解决方式:

在根目录编写jsconfig.json

{  "compilerOptions": {    "module": "commonjs",    "target": "es6",    "experimentalDecorators": true  },  "include": ["src/**/*"]}

2.2.3、对 observables 作出响应

computed

计算值是可以根据现有的状态或其它计算值衍生出的值, 跟vue中的computed非常相似。

computed 还可以直接当做函数来调用。 就像 observable.box(primitive value) 创建一个独立的 observable。 在返回的对象上使用 .get() 来获取计算的当前值,或者使用 .observe(callback) 来观察值的改变。 这种形式的 computed 不常使用,但在某些情况下,你需要传递一个“在box中”的计算值时,它可能是有用的。

示例:

import {observable, computed} from "mobx";var name = observable.box("hello");var upperCaseName = computed(() =>    name.get().toUpperCase());console.log("修改前:",name.get())upperCaseName.observe_(change => {  console.log("监听修改:",change.oldValue, change.newValue);});name.set("world");console.log("修改后:",name.get())

computed可作为装饰器, 将result的计算添加到类中:

import {observable, computed} from "mobx";class Store{  @observable arr = [];  @observable obj = {a: 1};  @observable map = new Map();  @observable str = 'hello';  @observable num = 123;  @observable bool = false;  @computed get result(){    return this.str + this.num;  }  }const store = new Store()console.log(store.result)

autorun

当你想创建一个响应式函数,而该函数本身永远不会有观察者时,可以使用 mobx.autorun

所提供的函数总是立即被触发一次,然后每次它的依赖关系改变时会再次被触发。

经验法则:如果你有一个函数应该自动运行,但不会产生一个新的值,请使用autorun。 其余情况都应该使用 computed

import {observable, computed, autorun} from "mobx";var numbers = observable([1,2,3]);var sum = computed(() => numbers.reduce((a, b) => a + b, 0));console.log('累加后:',sum.get())//会立即触发一次var disposer = autorun(() => {  console.log("监听:",sum.get())});//向数组中追加新值,会再次执行autorunnumbers.push(4);// disposer();numbers.push(5);

3、在react项目中使用mobx

3.1、环境搭建

create-react-app myappcd myappcnpm i react-app-rewired customize-cra -Dcnpm i @babel/plugin-proposal-decorators -Dcnpm i mobx mobx-react -S

在项目根目录下创建 config-overrides.js 文件

const { override, addDecoratorsLegacy } = require('customize-cra')module.exports = override(    addDecoratorsLegacy())

修改 package.json 文件中的启动命令:

{"scripts": {    "build": "react-app-rewired build",    "start": "react-app-rewired start",    "test": "react-app-rewired test",    "eject": "react-scripts eject"  }}

3.2、案例核心代码

参考以下目录结构创建文件:

- src	|-- components		|-- Button			|-- index.js		|-- Display			|-- index.js		|-- index.js	|-- store		|-- index.js
上一篇:[3D数学基础:图形与游戏开发]读书笔记 第9章(矩阵的更多知识、行列式、逆、正交矩阵、4x4齐次矩阵)未完待续


下一篇:windows激活失败之slmgr命令以记事本打开