安装
npm create umi
npm install
npm start
新增菜单和页面
关闭国际化配置
修改 config/defaultSettings.ts 中 menu.locale 设置为false
菜单新增
修改 config/config.ts , 增加 demo 菜单
...
{
path: '/admin',
name: 'admin',
icon: 'crown',
component: './Admin',
authority: ['admin'],
},
{
path: '/demo',
name: 'demo-测试',
icon: 'smile',
component: './demo/Index'
},
{
component: './404',
},
...
注意, /demo那一块是新加的,主要是path、name、component属性;特别注意一定要加在 /.404 上面。
增加页面
src/pages 目录下新建 demo目录,该目录下新建Index.tsx文件,Index.tsx文件内容如下:
import React, { Component } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { Card } from 'antd';
// eslint-disable-next-line react/prefer-stateless-function
class Index extends Component {
render() {
return (
<PageHeaderWrapper>
<Card>
hello world
</Card>
</PageHeaderWrapper>
);
}
}
export default Index;
效果图:
新增Table表格
service层
src/services 目录下新增 demo.ts
import request from '@/utils/request';
export async function queryDemo() {
return request('/test/demo');
}
mock层
mock 目录下新增demo.ts
export default {
'get /test/demo': (req, res) => {
res.json([
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
tags: ['nice', 'developer'],
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
tags: ['loser'],
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
tags: ['cool', 'teacher'],
},
]);
}
};
model层
src/models 目录下新增 demo.ts
import { queryDemo } from '../services/demo';
export default {
namespace: 'demo',
state: {
list: []
},
effects: {
* initData(params, sagaEffects) {
const {call, put} = sagaEffects;
let data = yield call(queryDemo);
yield put({
type: "queryList",
data: data
});
}
},
reducers: {
queryList(state, result) {
let data = [...result.data];
return {
list: data
};
}
}
};
page层
修改之前添加的 Index.tsx 文件
import React, { Component } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { Card, Table, Divider, Tag } from 'antd';
import { connect } from 'dva';
const namespace = "demo";
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
render: text => <a>{text}</a>,
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
},
{
title: 'Tags',
key: 'tags',
dataIndex: 'tags',
render: tags => (
<span>
{tags.map(tag => {
let color = tag.length > 5 ? 'geekblue' : 'green';
if (tag === 'loser') {
color = 'volcano';
}
return (
<Tag color={color} key={tag}>
{tag.toUpperCase()}
</Tag>
);
})}
</span>
),
},
{
title: 'Action',
key: 'action',
render: (text, record) => (
<span>
<a>Invite {record.name}</a>
<Divider type="vertical"/>
<a>Delete</a>
</span>
),
},
];
// eslint-disable-next-line react/prefer-stateless-function
@connect((state) => {
// 数据绑定到 this.props
return {
data: state[namespace].list
};
}, (dispatch) => {
// 函数绑定到 this.props
return {
initData: () => {
dispatch({
type: namespace + "/initData"
});
}
};
})
// @connect块 一定要紧接着 Component块 !!!
class Index extends Component {
componentDidMount() {
this.props.initData();
}
render() {
return (
<PageHeaderWrapper>
<Card>
<Table columns={columns} dataSource={this.props.data}/>
</Card>
</PageHeaderWrapper>
);
}
}
export default Index;
上面还有更简洁的写法:
import React, { Component } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { Card, Divider, Table, Tag } from 'antd';
import { connect } from 'dva';
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
render: text => <a>{text}</a>,
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
},
{
title: 'Tags',
key: 'tags',
dataIndex: 'tags',
render: tags => (
<span>
{tags.map(tag => {
let color = tag.length > 5 ? 'geekblue' : 'green';
if (tag === 'loser') {
color = 'volcano';
}
return (
<Tag color={color} key={tag}>
{tag.toUpperCase()}
</Tag>
);
})}
</span>
),
},
{
title: 'Action',
key: 'action',
render: (text, record) => (
<span>
<a>Invite {record.name}</a>
<Divider type="vertical"/>
<a>Delete</a>
</span>
),
},
];
class Index extends Component {
componentDidMount() {
this.props.dispatch({
type: "demo/initData"
});
}
render() {
return (
<PageHeaderWrapper>
<Card>
<Table columns={columns} dataSource={this.props.data}/>
</Card>
</PageHeaderWrapper>
);
}
}
export default connect(({demo}) => ({
data: demo.list
}))(Index);