在真實項目開發(fā)中,你可能會需要 Redux 或者 MobX 這樣的數(shù)據(jù)流方案,Ant Design React 作為一個 UI 庫,可以和任何 React 生態(tài)圈內(nèi)的數(shù)據(jù)流方案以及應(yīng)用框架搭配使用。我們基于 Redux 推出了自己的最佳實踐 dva,以及可插拔的企業(yè)級應(yīng)用框架 umi,推薦你在項目中使用。
dva 是一個基于 Redux 的 輕量級數(shù)據(jù)流方案,概念來自 elm,支持 side effects、熱替換、動態(tài)加載、react-native、SSR 等,已在生產(chǎn)環(huán)境廣泛應(yīng)用。
umi 則是一個可插拔的企業(yè)級 react 應(yīng)用框架。umi 以路由為基礎(chǔ)的,支持類 next.js 的約定式路由,以及各種進階的路由功能,并以此進行功能擴展,比如支持路由級的按需加載。然后配以完善的插件體系,覆蓋從源碼到構(gòu)建產(chǎn)物的每個生命周期,支持各種功能擴展和業(yè)務(wù)需求,同時提供 Umi UI 通過可視化輔助編程(VAP)提高開發(fā)體驗和研發(fā)效率。
你可能也會對 Ant Design Pro 感興趣,這是一個基于 umi、dva 和 ant design 的開箱即用的中臺前端/設(shè)計解決方案。
本文會引導(dǎo)你使用 Umi UI、dva 和 antd 從 0 開始創(chuàng)建一個簡單應(yīng)用。
推薦使用 yarn 安裝 Umi UI,執(zhí)行以下命令。
如果你使用 npm,可執(zhí)行 npm install umi -g,效果一致。
$ yarn global add umi
$ umi -v
2.10.4
確保 umi 版本在 2.10.0 以上。
啟動 Umi UI,
$ umi ui
?? Starting Umi UI using umi@2.10.4...
?? Ready on http://localhost:3000/
啟動后, Umi UI 會自動打開瀏覽器,點擊 創(chuàng)建項目,選擇路徑并輸入 應(yīng)用名,如下圖:
點擊 下一步,選擇 基礎(chǔ)模板,技術(shù)棧選上 antd 和 dva,然后點擊 完成。
進入到項目創(chuàng)建流程,等待幾分鐘,
創(chuàng)建完成后,進入到 總覽,點擊快捷入口 本地啟動,
在任務(wù)頁中,點擊 啟動,
按提示,點擊 http://localhost:8000,你會看到 umi 的歡迎界面。
前面選擇 antd 之后,會自動處理 antd 的依賴以及按需加載。你可以檢查 配置,確保 antd 已開啟。
而如果要使用固定版本的 antd,你可以在項目里安裝額外的 antd 依賴,package.json 里聲明的 antd 依賴會被優(yōu)先使用。
我們要寫個應(yīng)用來先顯示產(chǎn)品列表。首先第一步是創(chuàng)建路由,路由可以想象成是組成應(yīng)用的不同頁面。
然后通過命令創(chuàng)建 /products 路由,
$ umi g page products
create src/pages/products.js
create src/pages/products.css
? success
然后在瀏覽器里打開 http://localhost:8000/products,你應(yīng)該能看到對應(yīng)的頁面。
隨著應(yīng)用的發(fā)展,你會需要在多個頁面分享 UI 元素 (或在一個頁面使用多次),在 umi 里你可以把這部分抽成 component 。
我們來編寫一個 ProductList component,這樣就能在不同的地方顯示產(chǎn)品列表了。
點擊 在編輯器中打開,
然后新建 src/components/ProductList.js 文件:
import { Table, Popconfirm, Button } from 'antd';
const ProductList = ({ onDelete, products }) => {
const columns = [
{
title: 'Name',
dataIndex: 'name',
},
{
title: 'Actions',
render: (text, record) => {
return (
<Popconfirm title="Delete?" onConfirm={() => onDelete(record.id)}>
<Button>Delete</Button>
</Popconfirm>
);
},
},
];
return <Table dataSource={products} columns={columns} />;
};
export default ProductList;
完成 UI 后,現(xiàn)在開始處理數(shù)據(jù)和邏輯。
dva 通過 model 的概念把一個領(lǐng)域的模型管理起來,包含同步更新 state 的 reducers,處理異步邏輯的 effects,訂閱數(shù)據(jù)源的 subscriptions 。
新建 model src/models/products.js,
export default {
namespace: 'products',
state: [],
reducers: {
delete(state, { payload: id }) {
return state.filter(item => item.id !== id);
},
},
};
這個 model 里:
umi 里約定 src/models 下的 model 會被自動注入,你無需手動注入。
到這里,我們已經(jīng)單獨完成了 model 和 component,那么他們?nèi)绾未?lián)起來呢?
dva 提供了 connect 方法。如果你熟悉 redux,這個 connect 來自 react-redux。
編輯 src/pages/products.js,替換為以下內(nèi)容:
import { connect } from 'dva';
import ProductList from '../components/ProductList';
const Products = ({ dispatch, products }) => {
function handleDelete(id) {
dispatch({
type: 'products/delete',
payload: id,
});
}
return (
<div>
<h2>List of Products</h2>
<ProductList onDelete={handleDelete} products={products} />
</div>
);
};
export default connect(({ products }) => ({
products,
}))(Products);
最后,我們還需要一些初始數(shù)據(jù)讓這個應(yīng)用 run 起來。編輯 src/app.js:
export const dva = {
config: {
onError(err) {
err.preventDefault();
console.error(err.message);
},
initialState: {
products: [{ name: 'dva', id: 1 }, { name: 'antd', id: 2 }],
},
},
};
刷新瀏覽器,應(yīng)該能看到以下效果:
完成開發(fā)并且在開發(fā)環(huán)境驗證之后,就需要部署給我們的用戶了。點擊 構(gòu)建,
構(gòu)建會打包所有的資源,包含 JavaScript, CSS, web fonts, images, html 等。你可以在 dist/ 目錄下找到這些文件。
我們已經(jīng)完成了一個簡單應(yīng)用,你可能還有很多疑問,比如:
你可以:
更多建議: