什么是Umi.js?
umi,中文可發音為烏米,是一個可插拔的企業級 react 應用框架。你可以將它簡單的理解為一個專注性能的類 next.js 前端框架,並通過約定、自動生成和解析代碼等方式來輔助開發,減少我們開發者的代碼量。
為什么使用Umi.js?
我們做react開發的時候會不會遇到以下問題?:
1.項目做大的時候,開發調試的啟動和熱更新時間會變得很長。
2.大應用下,網站打開很慢,有沒有辦法基於路由做到按需加載。
3.dva的model每次都要手寫載入,能否一開始就同項目初始化好?
使用烏米,即可解決以上問題,並且還能提供如下優勢:
- 開箱即用,內置 react、react-router 等
- 類 next.js 且功能完備的路由約定,同時支持配置的路由方式
- 完善的插件體系,覆蓋從源碼到構建產物的每個生命周期
- 一鍵兼容到 IE9
- 完善的 TypeScript 支持
- 與 dva 數據流的深入融合
起步Umi
node環境安裝
在官網下載與系統相應的node版本,node.js版本>=8.10
安裝Umi
npm install -g umi
推薦使用 yarn 代替 npm 來安裝 umi , yarn 會針對部分場景做一些緩存以節省時間,你可以輸入以下命令來全局安裝 yarn,使用yarn后項目中盡量避免再使用npm,不然可能會發生意想不到的錯誤。
# 使用yarn安裝umi yarn global add umi
Umi快速上手
先找個地方建個空目錄myapp
# 新建應用 $ mkdir myapp && cd myapp # 新建頁面 $ umi generate page index # 本地開發 $ umi dev # 構建上線 $ umi build
項目工程結構
public // 公共文件 可以放一些第三方字體 樣式庫等 mock // mock文件 src |-- components // 公共組件目錄 當業務需要拆分組件的時候,可以在對應的業務文件夾下單獨創建一個components文件夾 |-- layouts // 項目結構文件 |-- locales // 規划文件 |-- models // 公共model存放位置 |-- public.js // 公共model文件 可以多個 |-- services // 公共api存放 |-- pages // 容器組件 |-- demo-umi // 業務容器 相對路由/demo ***不可以有任何大寫字母 |-- index.js // 業務入口 入口文件只識別index.js 后綴必須是js |-- index.less // 業務樣式 |-- modules // 業務model目錄 |-- demo-m.js // 業務model文件 可以有多個 自動加載 |-- service // 業務api目錄 |-- demo-s.js // 業務api文件 可以有多個 |-- utils // 工具 |-- theme |-- cofnig.js // 覆蓋antd樣式文件 |-- vars.less // 全局變量 |-- global.less // 公共樣式 覆蓋樣式 .eslintignore // eslint過濾文件清單 .eslintrc.js // eslint配置 .gitignore package.json README.md
約定式路由
啟動 umi dev 后,大家會發現 pages 下多了個 .umi 的目錄請不要直接在這里修改代碼,umi 重啟或者 pages 下的文件修改都會重新生成這個文件夾下的文件,約定 pages 下所有的 (j|t)sx? 文件即路由
使用dva
在 umi 項目中,你可以使用 dva 來處理數據流,以響應一些復雜的交互操作。
在 umi@^2 中要使用 dva 的功能很簡單,只要使用 umi-plugin-react 插件並配置 dva:true 即可。
修改配置的文件:./umirc.js
// ref: https://umijs.org/config/ export default { plugins: [ // ref: https://umijs.org/plugin/umi-plugin-react.html ['umi-plugin-react', { antd: true, dva: true, // 在此處啟用 dva dynamicImport: false, title: 'hero', dll: false, routes: { exclude: [], }, hardSource: false, }], ], }
在dva中,處理數據流的文件統一放在 models 文件夾下,每一個文件默認導出一個對象,里面包含數據和處理數據的方法,通常我們稱之為 model 。如以下count.js,model結構一般是如此:
./src/models/count.js
export default { namespace: 'count', // 默認與文件名相同 state: 'count', subscriptions: { setup({ dispatch, history }) { }, }, reducers: { update(state) { return `${state}_count`; }, }, effects: { *fetch({ type, payload }, { put, call, select }) { }, }, }
關於reducers,effects,subscriptions的詳細介紹,可參考dva.js官方文檔
在項目頁面中使用model
我們需要導入connect將頁面和model綁定在一起。import { connect } from 'dva'; function CountPage(props) { //從props屬性中打印namespace為count的model的state數據 console.log(props.count); return ( <div className={styles.normal}> <h1>數量大小</h1> <h2>This is {props.count}</h2> </div> ); } export default connect(({ count }) => ({ count }))(CountPage);
如果使用es7的裝飾器,我們可以改成這樣的寫法:
import { connect } from 'dva'; // 裝飾器 @connect(({ count }) => ({ count })) function CountPage(props) { //從props屬性中打印namespace為count的model的state數據 console.log(props.count); return ( <div className={styles.normal}> <h1>數量大小</h1> <h2>This is {props.count}</h2> </div> ); } export default CountPage;