入门案例
1、环境搭建
创建项目
mkdir my-app
cd my-app
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
构建项目结构
按照以下目录结构创建文件
- my-app
|-- src 源文件目录
|-- index.js 入口文件
|-- public 静态资源目录
|-- index.html
|-- webpack.config.js
|-- dist 打包后的静态文件目录
编写 index.html
文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
</body>
</html>
编写 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
})
]
}
在 package.json
文件中配置打包命令:
{
"scripts": {
"build": "webpack --mode production"
}
}
2、Mobx核心API
下面的代码需要在 src/index.js
中完成。
2.1、observable可观察的状态
- 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'));
- object
import {observable} from 'mobx'
// 声明
const obj = observable({a: 1, b: 2});
// 修改
obj.a = 11;
// 访问
console.log(obj.a, obj.b);
- 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、 observable装饰器
import { observable } from 'mobx'
class Store{
@observable arr = [];
@observable obj = {a: 'htllo'};
@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);
console.log(store.num);
注意:vscode编译器中,js文件使用装饰器会报红。解决方式:
在根目录编写 jsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"experimentalDecorators": true
},
"include": ["src/**/*"]
}
2.3、对 observables 作出响应
computed
计算值是可以根据现有的状态或其它计算值衍生出的值, 跟vue中的computed非常相似。
import { observable, computed } from 'mobx'
var name = observable.box("John");
var upperCaseName = computed(() =>
name.get().toUpperCase()
);
//name的属性值
console.log("name:",name.get());
console.log("转换后:",upperCaseName.get());
//对computed返回值做监听
var disposer = upperCaseName.observe_(change => {
console.log("监听到数据变化:",change.newValue,change.oldValue)
});
//对observable观察的属性做修改
name.set("Dave");
name.set("Lily");
autorun
import { observable, computed, autorun } from 'mobx'
const arry = observable([1,2,3])
const result = computed(()=>{
return arry.reduce((total,item)=>{
return total + item
})
})
//得到计算后的结果
console.log(result.get());
//会先触发一次监听,然后每次修改 arry 都会触发
autorun(()=>{
console.log('监听到修改的结果:', result.get());
})
//修改 observable 被观察对象的值
arry.push(4)
arry.push(5)
2.4、改变 observables状态
import { observable, action } from 'mobx'
class Store {
@observable num = 10
@action add(){
return this.num += 1
}
}
const store = new Store()
console.log(store.add());
3、案例应用
在react中使用mobx,需要借助mobx-react。
它的功能相当于在react中使用redux,需要借助react-redux。
首先来搭建环境:
create-react-app react-app
cd react-app
npm run eject
npm i @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties -D
npm i mobx mobx-react -S
修改package.json中babel的配置:
"babel": {
"presets": [
"react-app"
],
"plugins": [
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
[
"@babel/plugin-proposal-class-properties",
{
"loose": true
}
]
]
}
注意:vscode编译器中,js文件使用装饰器会报红。解决方式:
在根目录编写写jsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"experimentalDecorators": true
},
"include": ["src/**/*"]
}
在 src
目录下创建 store.js
,作为项目的全局状态管理
import {observable, computed, action} from 'mobx'
class Store {
@observable num = 10
@computed get sumOne() {
return this.num += 1
}
@action add = ()=>{
console.log(this);
return this.num += 10
}
}
const store = new Store()
export default store
在其他组件中就可以使用了,例如在 index.js
中使用
import React from 'react';
import ReactDOM from 'react-dom';
import store from './store';
console.log(store.num);
console.log(store.sumOne);
console.log(store.add());
ReactDOM.render(<div>hello</div>,document.getElementById('root'));