摘要:基于的管理框架,提供簡單快捷的開發范式。這里的更改會對請求參數生效只針對名字是的進行下面鉤子函數的執行用于在執行之后觸發。
vanex
基于mobx & mobx-react的React store管理框架,提供簡單快捷的開發范式。使用模式類似dva,但用起來比dva更簡單,開發效率更高!
github地址: https://github.com/alibaba/vanex
example地址: https://github.com/alibaba/va...
三個API搞定問題!簡單易上手,開發效率高。
如何使用vanex提供了一鍵初始化的start方法,入口文件可以像下面這樣開始:
import React from "react"; import App from "./App"; import { start, } from "vanex"; // model import user from "./models/User"; import todos from "./models/Todos"; start({ component: App, container: "#root", models: { user, todos } });
所以,只需要把你的model(類似于tarot的module)、React Container Component、Middleware(可選)、Relation傳遞進來,應用就能跑起來了。
介紹下幾個概念:
model: 數據管理,區別于tarot,其只有:name命名空間以及data、action兩個核心部分,action部分可以同時存放類似于Reducers以及Effects兩個部分的操作(作為優化,后續這里可以做拆分);
middleware:中間件,用于輔助異步處理。model重定義的一個action最終被執行的流程是這樣的:首先其會被mobx的action函數包一層,以避免掉每次更改數據都會觸發一次UI的重新渲染,然后其會被各個中間件依次執行,而每個中間件都有before/after/error三個操作,可以在不同的操作中對每一種操作做統一的處理;
relation:用于不同model之間的通信,基于監聽訂閱模式。
基于vanex的開發范式的container Component也是UI Component,UI Component像下面這樣:
import React, {Component, PropTypes} from "react"; // components import UserLogin from "./components/UserLogin"; import UserDetail from "./components/UserDetail"; import Todos from "./components/Todos"; import { inject, observer, } from "vanex"; // 注意先observer,后inject @inject("user") @observer export default class App extends Component { render() { // const user = this.props.user.toJSON(); console.log(this.props.user.toJSON()); const {user} = this.props; console.log("user.isLogin:", user.isLogin); if (user.isLogin !== true) { return; } return ( ); } }
這里的oberser來自于mobx的observer,inject則來自于mobx-react。如果想給一個Component同時注入多個model,則可以像下面這樣:
// start import React from "react"; import App from "./App"; import { start, } from "vanex"; // model import user from "./models/User"; import todos from "./models/Todos"; start({ component: App, container: "#root", models: { user, todos } });
import { inject, observer, } from "vanex"; @inject( stores => ({ user: stores.user, todos: stores.todos, }) ) @oberser class MyComponent extends Component{ constructor(props, context) { super(props, context); } render() { const { user, todos, } = this.props; return ({user.name}); } }
mobx的observer API,用于將React Component變成observable的(動態收集依賴),在對model中的某些數據做了操作之后,如果被修改的數據剛好被該React組件使用到了,就會觸發該組件的重新渲染,這也就是mobx能細粒度控制數據的原因所在。
mobx-react的inject API,用于指定將哪些model注入進React Component(this.props.modelName),也就指定了該組件基于哪些數據做Observeable。
model代碼類似于下面這樣:
import TodoItem from "./TodoItem"; import * as api from "../api"; export default { name: "Todos", data: { list: [], }, syncs: { add(text, userId) { // 類似于Vue,對數組的操作會觸發UI的重新渲染 this.list.push(new TodoItem({ text, userId })); }, }, effects: { async getByUserId(userId) { let todos = await api.getTodosByUserId(userId); todos = todos.map(todo => new TodoItem(todo)); // 類似于Vue,對數組的操作會觸發UI的重新渲染 this.list = this.list.concat(todos); }, } };
model由以下幾個部分組成:
1、name: 當前model的命名空間;
2、constants: 不可變常量;
3、data: 可操作數據部分;
4、syncs: 同步操作數據部分;
5、effects: 異步處理部分;
6、init: 初始化model后的回調方法;
7、autorun: 每次對數據進行操作后都會自動執行的方法。
觸發action model內部觸發model內部定義的Data數據,會被賦值到model實例上,所以任何在Data中定義的數據都可以通過this.xxx的方式來引用,如下:
import fetch from "whatwg-fetch"; const pageSize = 20; export default { name: "Applications", data: { dataSource: [ ], // 列表顯示的數據 detailPageVisible: false, campaignDetail: {}, }, syncs: { validate(value) { value = value ||""; // xxxx return { code: 200 }; }, }, effects:{ async getList(payload = {}) { const { currentPage = 1, } = payload; const url = `/applications/list/${currentPage}?pageSize=${pageSize}`; let res = await fetch(url); res = res.body; const validateRes = this.validate(res); if(validateRes.code == 200) { this.dataSource = res.data; // 這樣就會觸發對應Component的重新渲染 this.currentPage = res.currentPage; this.totalItem = res.totalItem; this.totalPage = res.totalPage; } return res; }, } };
可以看到,更改數據則是直接給model實例賦值即可,簡單直接高效,而且多次賦值只會觸發一次的重新渲染。你能想象如果一個頁面是一個list列表,用戶對列表中某一個進行操作后,需要修改這一項的數據及顯示,只需要執行類似于:
this.props.home.list[2].name = "New Name";
的代碼就能完成name的數據處理及頁面展示更改嗎?想想就激動是不是。
有的同學會有:syncs和effects里面多次對model直接賦值會觸發UI的多次渲染的擔心,其實不會的,我們隊syncs以及effects里面的每一個方法都用會使用mobx的action做了一層包裝,從而來避免這個問題。
另外,我們也提供this.set()的輔助方法來方便的為model改值,所以你還可以這樣做:
this.set({ dataSource: res.data, currentPage: res.currentPage, totalItem: res.totalItem, totalPage: res.totalPage, });
這里會使用mobx的runInAction來統一執行,從而保證UI渲染只執行一次。
組件內觸發如下,簡單直接:
import { inject, observer } from "vanex"; @inject("applications") @observer class Applications extends Component { constructor(props, context) { super(props, context); } clickHandler() { this.props.applications.getList(); // 直接執行 } render() { return ( ); } }Vanex插件機制
Vanex支持插件機制,使用的方式如下:
import { start, use } from "vanex"; import effectPlugin from "./effect-plugin"; use(effectPlugin); // start代碼
目前已經提供的插件列表如下:
onStateChange用于監聽數據發生改變的時候的觸發回調。格式如下:
export default { onStateChange: [event => { console.log(event); }] };onEffect
用于處理異步執行執行前(before)、后(after)、錯誤(error)以及過濾哪些effects執行該回調,它在執行的時候其實是以中間件的形式來執行的。如果有類似于每次請求都自帶csrfToken的需求,則可以在before鉤子函數中組裝。
具體使用如下:
// Before exec action function preLogger({ type, payload }) { console.log(`[${type}] params: `, payload); payload。csrfToken = "xxx"; // 這里的更改會對請求參數生效 return payload; } // Action exec fail function errorLogger({ type, payload }) { console.log(`[${type}] error: `, payload.message); return payload; } // After exec action function afterLogger({ type, payload }) { console.log(`[${type}] result: `, payload); return payload; } export default { filter({ type }) { return /^User/.test(type); // 只針對Model名字是User的進行下面鉤子函數的執行 }, before: preLogger, after: afterLogger, error: errorLogger, };onAction
用于在執行syncs Action之后觸發。格式如下:
export default { onAction: [( actionName, actionArgs, result) => { console.log(`當前執行Action的名字:${actionName}`); console.log(`當前執行Action的參數:${actionArgs}`); console.log(`當前執行Action的結果:${result}`); }] };getActionState
這個并不是Vanex插件,但是用于解決在組件中獲取當前model中某個effect是否正在發送請求的問題,而這個狀態可以用于方便的控制Loading組件是否可見。因為這種需求非常普遍,所以Vanex直接內置到內部實現中。使用示例如下:
const { user } = this.props; const { loading: loginLoading, error: loginError } = user.getActionState("user/login");用于開發組件
有時候,我們并不想執行頁面渲染,而是用Vanex來開發一個組件,這時,還是可以使用start API,只要不傳如container值,就會返回一個React Component。
import React from "react"; import { render } from "react-dom"; import App from "./App"; // load middlewares import middlewares from "./middlewares"; import { start, use, } from "vanex"; use({ onEffect: middlewares }); // model import user from "./models/User"; import todos from "./models/Todos"; // relation import relation from "./relations"; // 驗證start返回一個組件 const MyComponent = start({ component: App, models: { user, todos }, relation }); render(特點, document.querySelector("#root"));
簡單易上手,開發效率高;
MVVM:Vanex實現了基于React的MVVM開發范式,簡單直接,開發效率高;
更改store數據:直接賦值;
觸發action:直接執行store的action;
性能優化:自動做掉。
為什么基于mobx的開發范式更簡單高效?Mobx的實現思想和Vue幾乎一樣,所以其優點跟Vue也差不多:通過監聽數據(對象、數組)的屬性變化,可以通過直接在數據上更改就能觸發UI的渲染,從而做到MVVM、響應式、上手成本低、開發效率高,在數據管理上需要再詳細闡述下其區別。
Redux是建議全局唯一Store的,多個Reducers也會在傳遞給react-redux之前被合并成一個root reducer,任何數據的更改(通過Reducer)都會通過這一個store來觸發整個UI樹的重新渲染,如果不做任何的性能優化(pureRender等),就算VD(Virtual Dom)有了再高的效率提升,當頁面數據量、DOM數量大了,性能消耗也是非常大的。另外一點,Redux實現的對數據的管理是pull方式的,就是說其只能等待應用派發某個行為(Action),然后重新觸發UI的渲染,而做不到對行為的可預期;Mobx則不一樣,他是基于監聽數據的屬性變化來實現的,而且是多store的,對于任何的數據變更都是第一時間知道的,所以其實現方式是基于push的監聽訂閱模式而實現,這樣,他就可以做到對數據的可預測以及細粒度的控制,甚至可以通過修改React組件生命周期的方式來減少性能的消耗,而無需使用者對這些細節關心。當然這一切肯定是有了mobx對組件做observe操作才能實現的,所以也就有了observer用的越多,應用性能越高的說法。
感謝Vanex的部分實現參考自MVVM框架:mobx-roof。
落地1、內容創作投放平臺
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/87347.html
摘要:前言作為官方的腳手架是相當好用的。注意就是腳手架的核心配置代碼。另一個是使用,用戶通過增加修改配置。所以才有了今天的主題基于的腳手架,確切說應該是基于的腳手架。其中一定要填寫。前言 create-react-app作為facebook官方的react腳手架是相當好用的。主要設計原理是將配置好的如Webpack,Babel,ESLint,合并到react-scripts這npm包中,用戶就可以...
摘要:平臺上的微服務架構應用再來看一下我眼中的基于當前最流行的微服務架構的設計是什么樣的,即我們平臺上要運行的典型應用是什么樣的。 showImg(https://segmentfault.com/img/remote/1460000010900878); 8月19日的數人云Container Meetup上,張龍老師做了《基于Kubernetes的PaaS平臺的設計和思考》的精彩分享,分別...
摘要:由進行開發和維護,代發布于年月,現在主要是。狀態是只讀的,只能通過來改變,以避免競爭條件這也有助于調試。文件大小為,而為,為。請記住,性能基準只能作為考慮的附注,而不是作為判斷標準。使用的人員報告說,他們永遠不必閱讀庫的源代碼。 本文當時寫在本地,發現換電腦很不是方便,在這里記錄下。 angular,react & vue 2018/07/23 2016年,對于JavaScript來說...
摘要:感謝大神的免費的計算機編程類中文書籍收錄并推薦地址,以后在倉庫里更新地址,聲音版全文狼叔如何正確的學習簡介現在,越來越多的科技公司和開發者開始使用開發各種應用。 說明 2017-12-14 我發了一篇文章《沒用過Node.js,就別瞎逼逼》是因為有人在知乎上黑Node.js。那篇文章的反響還是相當不錯的,甚至連著名的hax賀老都很認同,下班時讀那篇文章,竟然坐車的還坐過站了。大家可以很...
閱讀 3114·2023-04-26 01:58
閱讀 958·2021-11-24 09:38
閱讀 3291·2021-09-03 10:29
閱讀 721·2021-08-21 14:10
閱讀 1494·2019-08-30 15:44
閱讀 3094·2019-08-30 14:10
閱讀 3218·2019-08-29 16:32
閱讀 1484·2019-08-29 12:48