dva是支付寶前端團隊時常維護的一個開源項目,會維護,維護,維護!!它集成了redux , react-router , 可能還用到了TypeScript等等,看github上說是基於react的最佳實踐,使用下來確實感受挺不錯的。組件我沒有用antd而是本身寫的。css
首先你須要安裝node我想應該前端都會用吧,固然react你也必須會。若是不會react和前端基礎那估計你要去補一補了咯html
npm install dva-cli -g複製代碼
dva new newDva
進入項目目錄執行npm start 就能夠看到你初始化的項目了複製代碼
routes 和 models 兩個文件夾是最重要的兩個裏面會有大量內容
utils 裏面放的基本上是工具函數本身封裝或者別的地方拿
services 裏面基本是一些網絡請求的api 在 models文件裏面的 effects 內會用到
assets 裏面會有一些靜態的圖片之類的前端
整個app 主要的邏輯加上組件都在src這個大的文件夾下面
mock 裏面就是模擬的api接口node
啓動項目,自動檢測文件變化熱更新頁面。react
打包項目。會在文件名後加上一個hash值而且壓縮文件git
建立一個路由,而且在router.js中自動註冊這個路由。其實route目錄下放的就是全部頁面組件,他建立的就是一個頁面。
會有兩個文件,我的建議不用這個指令,手動建立文件夾做爲一個頁面,當前頁面的全部組件放在這個文件夾裏面,公共組件能夠放在components文件夾下es6
import React from 'react';
import { connect } from 'dva';
import styles from './IndexPage.css';
function IndexPage() {
return (
....
);
}
IndexPage.propTypes = {
};
export default connect()(IndexPage);複製代碼
這是初始化以後的首頁組件模板,dva提倡狀態組件。大體就是你沒法在一個dva組件裏面使用生命週期。
參數狀態有對應的model去控制,函數類型組件直接返回html模板多是一種對react的性能優化,固然你也能夠在return中嵌套別的自定義組件。return <OtherComponent />
一個頂級標籤的規矩仍是不能破壞的
在這裏面css能夠看到是以一個對象形式引入,實際上是dva採用了css-model這種方式。具體的能夠去看css-model。使用寫法是這樣:<OtherComponent className={style.one} />
若是你要多個className 那你須要這樣寫<OtherComponent className={style.one + " " + style.another} />
github
這個指令很是好用,他會建立一個example.js的文件做爲一個模型,而且在router.js中自動註冊這個模型。app.model(require('./models/example'));
這裏的一個模型應該和route裏面的文件夾一一對應起來,至關於平時使用的redux。裏面有當前這個路由組件的state,具體是長這個樣子的npm
export default {
namespace: 'example',
state: {},
subscriptions: {
setup({ dispatch, history }) { // eslint-disable-line
},
},
effects: {
*fetch({ payload }, { call, put }) { // eslint-disable-line
yield put({ type: 'save' });
},
},
reducers: {
save(state, action) {
return { ...state, ...action.payload };
},
},
};複製代碼
namespace 是這個model的命名,他是一個全局的,只能出現一個,並且最好是和組件對應,redux
state是這個model裏面的數據,也是他對應組件的state
dispatch 是觸發方法的一個函數,在model裏面使用可使用
subscriptions:我認爲至關於組件的全部生命週期均可以在這裏找到對應的api去調用,經常使用是setup在組件渲染以前會觸發,setup通常是直接出發effects裏面的方法
> dispatch({ type: 'fetch'}); //若是是當前model能夠直接寫方法名
若是是別的model的那你須要前面加上model名字 { type: 'OtherModel/fetch'}複製代碼
effects:全部網絡請求都應該放在這裏面,應爲它使用了generator來處理異步,這裏是惟一一個地方能夠處理異步請求的。固然你要大牛能夠本身在別的地方寫咯。
const data = yield call( apiFunction );
拿到請求回來的數據了;const data = yield put( { type : "save" , payload :{data} );
調用當前組件的save方法存入當前的state,其實這裏和subscriptions中的dispatch方法相似;const data = yield select( { modelName } => modelName.stateValue );
import { routerRedux } from 'dva/router'; yield put( routerRedux.push("/targit"));
reducers:這裏面放的全是改變state的函數傳入兩個參數,當前model的state和數據,在這裏利用傳入的數據對state進行修改。通常會在effects裏面被調用,或者是在和這個模塊綁定的組件裏面經過事件回調,
dispatch({ type: 'save'})
經過函數參數方式傳入
導出涌dva的connect方法鏈接組件和model;
const IndexPage = ({ dispatch, example })=> {
return <Index />
}
export default connect(({ example }) => ({
example
}))(IndexPage);複製代碼
那麼你在這個組件裏面就能夠拿到example這個model的全部state和dispatch這個方法
state:example.stateName獲取這個model的一個state屬性值
爲了能在組件中觸發model的方法作一系列的操做那麼就須要使用dispatch了
在組件事件中觸發
function(){ dispatch({ type : "model/name" payload : "" }) }複製代碼
觸發了這個model的name方法作了一系列操做;
那你也能夠用class 來聲明一個組件複製代碼
class AppointmentPage extends React.Component {
handleClick(){
this.props.dispatch({
type: 'modelName/name'
})
}
render(){
return (...)
}
}
export default connect(({ modelName }) => ({
modelName
}))(Component);複製代碼
dispatch方法會在this.props裏面。
我採用了nodejs做爲本地服務器
須要在.roadhogrc文件中添加
"proxy": {
"/api": {
"target": "http://127.0.0.1:3000/api/",
"changeOrigin": true,
"pathRewrite": { "^/api" : "" }
}
},複製代碼
讓他去代理你的後臺服務那麼你在請求的時候地址只須要寫 「api/...」 推薦使用fetch。
因爲以前開源協議的緣由可能會用不少大佬放棄react什麼的啊,可是我以爲若是是作開源項目徹底不必,企業內部呢厲害的應該會本身封裝相似的,大部分服務於國內的項目其實沒什麼必要換,Facebook根本進不來嘛,並且這樣的思路值得學習。
dva的使用一開始可能會很是不適應,可是寫過以後感受仍是很是nice的結構清晰,寫法也不復雜,事件處理都封裝的不錯,特別是在redux這裏的封裝,使用起來很是舒服,若是本身寫估計就不是這麼一點複雜度了,命令行指令善用。dva用了較多的解構賦值箭頭語法generator等等,不會的要多看es6。放一張圖幫助理解