前端学习——Mobx
webpack環(huán)境搭建
npm init -ynpm i webpack webpack-cli webpack-dev-server -Dnpm i html-webpack-plugin -Dnpm i babel-loader @babel/core @babel/preset-env -Dnpm i @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties -Dnpm i mobx -S編寫webpack.config.js
const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = {mode: 'development',entry: {app: path.resolve(__dirname, './src/index.js')},output: {path: path.resolve(__dirname, './dist')},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()],// 代碼合并方式在一行devtool:'inline-source-map' }observable可觀察對象
import {observable} from 'mobx'map
set設(shè)置,get獲取,delete刪除,has判斷有無
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.has('a'));數(shù)組
數(shù)組轉(zhuǎn)成可觀察的后是proxy,訪問和操作與js相同
const arr = observable([1,2,3,4,5]) // arr是一個(gè)proxy console.log(arr[2]); arr.pop() arr.push(12) console.log(arr);對象
對象轉(zhuǎn)成可觀察的后是proxy
let obj = observable({a:1,b:2}) console.log(obj);//obj是一個(gè)proxy基礎(chǔ)類型
枚舉,布爾值,字符串需要放入box,使用get訪問,使用set設(shè)置
枚舉
const num = observable.box(10)console.log(num.get());字符串
const str = observable.box('str') console.log(str.get());布爾值
const bool = observable.box(true) console.log(bool.get());observable裝飾器
對 observables 作出響應(yīng)
autorun
檢測數(shù)據(jù)變化,數(shù)據(jù)必須是可觀察的
參數(shù)是一個(gè)回調(diào)函數(shù)
第一次運(yùn)行會(huì)調(diào)用,回調(diào)函數(shù)被引用的數(shù)據(jù)有變化會(huì)調(diào)用
用于檢測回調(diào)函數(shù)里對象的變化
let obj = observable({title:'msg'}) autorun(()=>{console.log(obj.title); }) obj.title = 'mmm'when
有兩個(gè)參數(shù),都是回調(diào)函數(shù),第一個(gè)回調(diào)函數(shù)返回布爾值,為true才運(yùn)行第二個(gè)回調(diào)函數(shù)
when(()=>{return store.bool},()=>{console.log('when function run...');} )reaction
autorun的變種
基于某個(gè)數(shù)據(jù)實(shí)現(xiàn)視圖更新
兩個(gè)參數(shù),均為回調(diào)函數(shù),第一個(gè)回調(diào)函數(shù)的返回值作為第二個(gè)回調(diào)函數(shù)的輸入
和autorun的區(qū)別:第一次不會(huì)調(diào)用,發(fā)生變化時(shí)調(diào)用
reaction(()=>{return store.str},(arr)=>{console.log(arr.join('/'));} ) setTimeout(() => {store.bool = true,store.str = 'world'store.num = 220 }, 5000);computed
定義方法:
1.computed函數(shù)(使用不多)
對觀察的結(jié)果可以使用observer方法
const rs = computed(()=>{return store.str+store.num }) console.log(rs.get()); rs.observe((change)=>{console.log(rs.get()); })store.bool = true, store.str = 'world' store.num = 2202.裝飾器定義computed
@computedget result(){return this.str+this.num} //使用reaction檢測變化 reaction(()=>{return store.result},(result)=>{console.log(result);} )改變observable的狀態(tài)
action
mobx中引入action對象,通過裝飾器裝飾函數(shù)
@actionbar(){this.str = 'mobx',this.num = '232'} store.bar()綁定this
@action.bound foo(){this.str = 'foo'}異步操作
npm i @babel/runtime @babel/plugin-transform-runtime
在webpackconfig.js里配置
@actionasync fzz(){console.log('fzz');let obj = await new Promise((reslove)=>{setTimeout(() => {reslove({num:1234,str:'wowo'})}, 4000);})runInAction(()=>{store.num = obj.numstore.str = obj.str})console.log(store.num,store.str);}在react中使用mobx
npx create-react-app react-mobx-appcreate-react-app不支持裝飾器
二次配置webpack的方法:cra,rewied,eject
yarn eject npm i @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties -D在package.json里配置babel
"babel": {"presets": ["react-app"],"plugins":[["@babel/plugin-proposal-decorators",{"legacy":true}],["@babel/plugin-proposal-class-properties",{"loose":true}]]} npm i mobx mobx-react -S yarn start注意:vscode編譯器中,js文件使用裝飾器會(huì)報(bào)紅。解決方式:
在根目錄編寫寫jsconfig.json
{"compilerOptions": {"module": "commonjs","target": "es6","experimentalDecorators": true},"include": ["src/**/*"] }React + Mobx 案例
創(chuàng)建store/index.js
import {observable, action, computed,runInAction} from 'mobx' class AppStore{@observabletitle = 'mobx'@observabletodos = []@computedget desc(){return `一共${this.todos.length}條`}@action.boundaddTodo(todo){//可以直接操作數(shù)據(jù)this.todos.push(todo)}@action.bounddelTodo(){this.todos.pop()}@action.boundresetTodo(){this.todos = []}@action.bound//異步操作方法1// asyncAddTodo(todo){// this.todos.push(todo)// }//異步操作方法2async asyncAddTodo(todo){await new Promise((resolve)=>{setTimeout(() => {resolve() }, 1000);})runInAction(()=>{this.todos.push(todo)})}} const store = new AppStore() //導(dǎo)出類的實(shí)例 export default store創(chuàng)建pages/Home.js,在這里使用store
import React, { Component } from 'react' import {observer,inject} from 'mobx-react' import store from '../store' //觀察者observer:類被引用后,屬性發(fā)生變化,重新渲染類 // inject可以傳入?yún)?shù), // 類可以響應(yīng)變化,根據(jù)變化做出渲染或修改數(shù)據(jù) @inject('store') @observer class Home extends Component {addTodo=(item)=>{return()=>{store.addTodo(item)}}delTodo=()=>{store.delTodo()}resetTodo=()=>{store.resetTodo()}asyncAddTodo=(item)=>{return ()=>{setTimeout(() => {store.asyncAddTodo(item)}, 2000);}}render() {return (<><div>{store.title}</div><button onClick = {this.addTodo('這是一條內(nèi)容')}>add</button><button onClick = {this.delTodo}>delete</button><button onClick = {this.resetTodo}>reset</button><button onClick = {this.asyncAddTodo('這是一條異步添加內(nèi)容')}>async add</button><h6>{store.todos.length}</h6>{store.todos.map((item,index)=>{return(<div key = {index}>{item}</div>)})}</>)} } export default Home n onClick = {this.resetTodo}>reset</button><button onClick = {this.asyncAddTodo('這是一條異步添加內(nèi)容')}>async add</button><h6>{store.todos.length}</h6>{store.todos.map((item,index)=>{return(<div key = {index}>{item}</div>)})}</>)} } export default Home總結(jié)
以上是生活随笔為你收集整理的前端学习——Mobx的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 标称型和数值型(连续型)的区别
- 下一篇: 【光通信】参数'G'和'GE’的技术实现