在官網下載與系統相應的node版本,node.js版本>=8.10css
推薦使用Visual Studio Code 安裝方法html
npm install -g umi
推薦使用 yarn 代替 npm 來安裝 umi , yarn 會針對部分場景作一些緩存以節省時間,你能夠輸入如下命令來全局安裝 yarn,使用yarn後項目中儘可能避免再使用npm,否則可能會發生意想不到的錯誤。
npm install -g yarn # 安裝完成後,使用命令查看是否安裝成功 yarn -v # 使用yarn安裝umi yarn global add umi # 安裝完成後,使用命令查看是否安裝成功 umi -v
建立項目文件後使用終端工具打開文件node
推薦使用 yarn create 命令,能確保每次使用最新的腳手架。react
yarn create umi / npm create umi
若是提示 create-umi 命令不存在,你須要執行 yarn global bin,而後把 global bin 的路徑添加到環境變量 PATH 中。
? Select the boilerplate type (Use arrow keys) ant-design-pro - Create project with an layout-only ant-design-pro boilerplate, use together with umi block. ❯ app - Create project with a simple boilerplate, support typescript. block - Create a umi block. library - Create a library with umi. plugin - Create a umi plugin.
? Do you want to use typescript? (y/N)
功能介紹詳見 plugin/umi-plugin-reactgit
? What functionality do you want to enable? (Press <space> to select, <a> to toggle all, <i> to invert selection) ❯◯ antd ◯ dva ◯ code splitting ◯ dll
啓動項目 yarn start / npm run start
在.env文件中可更改環境配置,通常不須要更改,常見更改例如github
# 更改服務啓動端口號 PORT=8001 # 關閉自動打開瀏覽器,默認爲打開 BROWSER=none
詳細配置web
編譯時的配置文件,.umirc.(js|ts) 和 config/config.(js|ts),兩者選一,不可共存
推薦在主文件夾下建立config文件,使用config.js進行項目配置(刪除自動搭建項目時建立的.umirc.(js|ts))
詳細配置
config.local.js和config.production.js可在此配置開發環境和線上環境不一樣的配置,在進行打包時需修改package.json中腳本代碼typescript
# 下載cross-env開啓代碼分割功能 yarn add -D cross-env / npm install --save-dev cross-env # package.json中 "scripts"修改 "build": "cross-env UMI_ENV=production umi build"
根據實際狀況進行後綴添加,不然ts會報導入錯誤npm
declare module "*.png"; declare module "*.jpg"; declare module '*.less';
修改tslint規則,可根據我的使用狀況修改,詳細配置可見tslint-react相關約定規則json
# 推薦修改 rules: eofline: true no-console: true no-construct: true no-debugger: true no-reference: true no-trailing-whitespace: false jsx-no-multiline-js: false jsx-alignment: false jsx-no-lambda: false
"experimentalDecorators": true
存放mock.js,默認開啓mock功能,可在.env文件中關閉: MOCK=none
全部與項目相關代碼存放在src文件之中
存放靜態資源,例如圖片文件、字體文件等
存放全局通用組件
全局佈局,若是該文件夾下有index.(js|tsx)會在全部路由外面嵌套一層路由
例如以前路由爲
[ { path: '/', component: './pages/index' }, { path: '/users', component: './pages/users' }, ]
嵌套以後爲
[ { path: '/', component: './layouts/index', routes: [ { path: '/', component: './pages/index' }, { path: '/users', component: './pages/users' }, ] } ]
可在index文件中進行全局佈局,或者根據pathname修改不一樣路由下的佈局
全局models,若是有一個以上的頁面會使用相同namespace空間內的代碼,請將models文件放在此處,否則兩個頁面之間作交互時,
namespace中的代碼會產生影響
存放通用樣式,若是想覆蓋全局樣式可在global.(css|less|sass|scss)進行修改,此文件不走 css modules,且會自動被引入。
或者在app.(js|ts)中導入樣式文件
存放全局通用請求
存放通用方法
這是 umi dev 時生產的臨時目錄,默認包含 umi.js 和 router.js,有些插件也會在這裏生成一些其餘臨時文件。能夠在這裏作一些驗證,但請不要直接在這裏修改代碼,umi 重啓或者 pages 下的文件修改都會從新生成這個文件夾下的文件。
該文件下的router.js可查看自動生成的路由
項目頁面文件,在不一樣文件中建立的components、models、services文件最好只在該頁面中使用,可以使項目結構變得更加清晰
該文件爲測試腳本文件,不會生成路由配置,若是須要使用mock測試,能夠在外部mock文件中或者在該文件下建立__mock__文件
在 umi 項目中,你能夠使用 dva 來處理數據流,以響應一些複雜的交互操做。這些處理數據流的文件統一放在 models 文件夾下,每個文件默認導出一個對象,裏面包含數據和處理數據的方法,一般咱們稱之爲 model 。一個 model 文件的結構通常是這樣的:
export default { namespace: 'example', // 這個 model 的名字,必須全局惟一,不然相同namespace的代碼會產生影響 state: { count: 0, }, // 初始數據 reducers: { save() { ... }, }, // 用於修改數據 effects: { *getData() { ... }, }, // 用於獲取數據 subscriptions: { setup() { ... }, }, // 用於訂閱數據 }
每個 reducer 都是一個普通函數,接受 state 和 action 做爲參數,即:(state, action) => state ,你能夠在函數中更改舊的 state,返回新的 state 。
reducers: { save(state, { payload }) { return ({ ...state, ...payload }); }, },
每個 effect 都是一個 生成器函數 ,你能夠在這裏獲取你須要的數據,例如向服務器發起一個請求、或是獲取其餘 model 裏的 state 。爲了明確分工,你沒法在 effect 中直接修改 state ,但你能夠經過 put 方法 調用 reducer 來修改 state
state:{ assets:{}, }, *changeAssets({ payload }, { call, put, select }) { const user = yield select(states => states.user); const assets = yield call(fetchData, user); yield put({ type: 'save', payload: { assets } }); },
此方法用於獲取當前或其餘 model 的 state 。
const data = yield select(states => states[namespace]);
此方法用於執行一個異步函數,能夠理解爲等待這個函數執行結束。項目中經常使用於發送 http 請求,等待服務端響應數據。
const data = yield call(doSomethingFunc, parameter);
此方法用於觸發一個 action,這個 action 既能夠是一個 reducer 也能夠是一個 effect 。
yield put({ type: 'reducerName', payload: { page } });
subscription 用於訂閱一個數據源,根據須要使用 dispatch 觸發相應的 action。數據源能夠是當前的時間、服務器的 websocket 鏈接、keyboard 輸入、geolocation 變化、history 路由變化等等。 項目中經常使用於頁面初始化數據的自動請求,如:
subscriptions: { setup({ dispatch, history }) { return history.listen(({ pathname, query }) => { // 進入 '/home' 路由,發起一個名叫 'query' 的 effect if (pathname === '/home') { dispatch({ type: 'query' }); } }); }, },
相似 effect 中的 put 方法,你能夠在 subscription 的參數、或是一個已經 connect 過的組件的 props 中拿到。
經過此方法在你的組件中獲取到指定 model 的 state 數據。
import { connect } from 'dva'; function App({ user, dispatch }) { const handleClick = () => { dispatch({ type: 'user/fetchUser' }); }; return ( <div> <h2>Hello, {user}</h2> <button onClick={handleClick}>Click me</button> </div> ); } export default connect(({ user }) => ({ user }))(App);
若是使用es7的裝飾器則爲
import { connect } from 'dva'; @connect(({ user }) => ({ user })) function App({ user, dispatch }) { const handleClick = () => { dispatch({ type: 'user/fetchUser' }); }; return ( <div> <h2>Hello, {user}</h2> <button onClick={handleClick}>Click me</button> </div> ); } export default App;