环境准备
首先得有 node,并确保 node 版本是 10.13 或以上。(mac 下推荐使用 nvm 来管理 node 版本)
$ node -v
v10.13.0
推荐使用 yarn 管理 npm 依赖,并使用国内源(阿里用户使用内网源)。
国内源
$ npm i yarn tyarn -g
后面文档里的 yarn 换成 tyarn
$ tyarn -v
阿里内网源
$ tnpm i yarn @ali/yarn -g
后面文档里的 yarn 换成 ayarn
$ ayarn -v
脚手架
先找个地方建个空目录。
$ mkdir myapp && cd myapp
通过官方工具创建项目,
$ yarn create @umijs/umi-app
或 npx @umijs/create-umi-app
Copy: .editorconfig
Write: .gitignore
Copy: .prettierignore
Copy: .prettierrc
Write: .umirc.ts
Copy: mock/.gitkeep
Write: package.json
Copy: README.md
Copy: src/pages/index.less
Copy: src/pages/index.tsx
Copy: tsconfig.json
Copy: typings.d.ts
安装依赖
$ yarn
yarn install v1.21.1
[1/4] 🔍 Resolving packages…
success Already up-to-date.
✨ Done in 0.71s.
启动项目
$ yarn start
Starting the development server…
✔ Webpack
Compiled successfully in 17.84s
DONE Compiled successfully in 17842ms 8:06:31 PM
App running at:
- Local: http://localhost:8000 (copied to clipboard)
- Network: http://192.168.12.34:8000
在浏览器里打开 http://localhost:8000/,能看到以下界面,
在umirc.js中有路由配置文件,如果想使用约定式路由,也就是umi自动根据你的文件生成路由就需要巴配置的路由删掉。约定 pages 下所有的 (j|t)sx? 文件即路由
global.css文件是全局css文件
src/layouts/index.js
约定式的全局布局,实际上是在路由外面套了一层。比如,你的路由是:
[
{
path: '/',
component: './pages/index,
},
{
path: '/users',
component: './pages/users',
},
]
如果有 layouts/index.js,那么路由则变为:
{
path: '/',
component: './layouts/index',
routes: [
{
path: '/',
component: './pages/index',
},
{
path: '/users',
component: './pages/users',
},
],
},
]
从组件角度来说也就是
<layout>
<page>1</page>
<page>2</page>
</layout>
关于dva的说明
model.js
import {Reducer,Effect,Subscription} from 'umi'
import getRemoteList from './service'
interface UserModelType{
namespace:'users';
state:{
data:[]
};
reducers:{
getList:Reducer
};
effects:{
getRemoteData:Effect
};
subscriptions:{
setup:Subscription
}
}
const UserModal:UserModelType={
namespace:'users',
state:{},
reducers:{
//同步提交数据的方法
getList(state,{payload})
{
//因为action是从effect得到的action
return payload
//返回一个newState
}
},
effects:{
//异步提交的方法
//所有函数前必须加*,变成generator函数
//然后函数内部的函数要加yield
//然后只能同步提交数据,所以只能put给reducers
//yield put(action)
//函数参数格式为*(action,effects)=>void没有返回值
//action=>{type,payload} effects=>{ put,call}
*getRemoteData({type,payload},{ put,call})
{
//调用函数必须用call
const data=yield call(getRemoteList)
if(data)
{
yield put({
type:'getList',
payload:data
})
}
}
},
subscriptions:{
//页面向数据订阅的方法,相当于监听
//函数参数为({dispatch,history}){}
/**
* dispatch(action)
* action为对象
* action={
* type:'需要派发函数的名字',
* payload:{需要派发函数的参数}
* }
*/
setup({dispatch,history})
{
history.listen((location)=>{
if(location.pathname==='/users'){
dispatch({
type:"getRemoteData"
})
}
})
}
}
};
export default UserModal
从后端获取数据
import { request } from 'umi'
const BaseURI='http://public-api-v1.aspirantzhang.com'
const getRemoteList=async =>{
return request('http://public-api-v1.aspirantzhang.com/users',{
method:'get'
}
)
.then(res=>{
return res
})
}
export default getRemoteList
连接到主页面
import { Table, Tag, Space } from 'antd';
import React from 'react';
import {connect} from 'umi'
const index=({users})=>{
const columns = [
{
title: 'ID',
dataIndex: 'id',
key: 'id'
},
{
title: 'Name',
dataIndex: 'name',
key: 'name',
},
{
title: 'Create_time',
dataIndex: 'create_time',
key: 'create_time',
},
{
title: 'Action',
key: 'action',
render: (text, record) => (
<Space size="middle">
<a>Edit {record.name}</a>
<a>Delete</a>
</Space>
),
},
];
return (
<div className="list-table">
{console.log(users)}
<Table columns={columns} dataSource={users.data} />
</div>
)
}
const mapStateToProps=(({users})=>{
return {
users
/**
* 使用 connect() 前,需要先定义 mapStateToProps
* 这个函数来指定如何把当前 Redux store state 映射到展示组件的 props 中。
*/
}
})
export default connect(mapStateToProps)(index);