Table of contents
1: What is Ant Design ?
Ant Design is a UI component developed by the Alibaba Ant Financial team based on React . It is mainly used for the use of mid- and back-end systems.
Official website: https://ant.design/index-cn
Design language:With the trend of commercialization, more and more enterprise-level products have further requirements for better user experience. With such an ultimate goal, we (Ant Financial Experience Technology Department) gradually polished a design system Ant Design that serves enterprise-level products through a large number of project practices and summaries . Based on the design values of "certainty" and "nature", through modular solutions, redundant production costs are reduced, allowing designers to focus on better user experience.
characteristic:
- The interactive language and visual style extracted from enterprise-level mid- and back-end products.
- High-quality React components ready to use out of the box .
- Built with TypeScript , providing complete type definition files.
- Full-link development and design tool system.
Two: Start using
Introducing Ant Design
Ant Design
is a design system that serves enterprise-level products. The component library is its
React
implementation.
antd
is released as an
npm
package for developers to install and use.
In
umi , you can
open the antd plug-in by configuring antd
in the plug-in set
umi-plugin-react
. The antd plug-in will help you introduce antd and implement on-demand compilation.
Configure in the configure.js
file :
export default {
plugins: [
['umi-plugin-react', {
dva: true, // 开启dva功能
antd: true // 开启Ant Design功能
}]
]
};
Small scale chopper
Next, we start using
antd
components, taking
the tabs
component as an example, the address is
https://ant.design/components/tabs-cn/
Effect:
Take a look at the official usage examples:
import { Tabs } from 'antd';
const TabPane = Tabs.TabPane;
function callback(key) {
console.log(key);
}
ReactDOM.render(
<Tabs defaultActiveKey="1" onChange={callback}>
<TabPane tab="Tab 1" key="1">Content of Tab Pane 1</TabPane>
<TabPane tab="Tab 2" key="2">Content of Tab Pane 2</TabPane>
<TabPane tab="Tab 3" key="3">Content of Tab Pane 3</TabPane>
</Tabs>,
mountNode);
Below we refer to the official examples for use:
Create the
MyTabs.js
file:
import React from 'react'
import {Tabs} from 'antd'
const TabPane = Tabs.TabPane;
const callback = (key) => {
console.log(key);
}
class MyTabs extends React.Component {
render() {
return (
<Tabs defaultActiveKey="1" onChange={callback}>
<TabPane tab="Tab 1" key="1">Content of Tab Pane 1</TabPane>
<TabPane tab="Tab 2" key="2">Content of Tab Pane 2</TabPane>
<TabPane tab="Tab 3" key="3">Content of Tab Pane 3</TabPane>
</Tabs>
)
}
}
export default MyTabs;
Effect:
At this point, we have mastered the basic use of antd components.
Three: Layout
antd
layout:
https://ant.design/components/layout-cn/
In the background system page layout, it is often a classic three-part layout, like this:
Next, we complete this layout through the antd component.
Component overview
- Layout : Layout container, under which Header Sider Content Footer or Layout itself can be nested, and can be placed in any parent container.
- Header : top layout, comes with default style, any element can be nested under it, and can only be placed in Layout .
- Sider : Sidebar, with its own default style and basic functions. Any element can be nested under it and can only be placed in Layout .
- Content : The content part has its own default style. Any element can be nested under it and can only be placed in Layout .
- Footer : Bottom layout, comes with default style, any element can be nested under it, and can only be placed in Layout .
Build an overall framework
Create the layouts directory in
the src directory
, create the index.js file in the layouts directory , and write the content:
import React from 'react'
import { Layout } from 'antd';
const { Header, Footer, Sider, Content } = Layout;
class BasicLayout extends React.Component{
render(){
return (
<Layout>
<Sider>Sider</Sider>
<Layout>
<Header>Header</Header>
<Content>Content</Content>
<Footer>Footer</Footer>
</Layout>
</Layout>
);
}
}
export default BasicLayout;
It should be noted that in the directory structure agreed in umi , the layouts/index.js file will be used as the global layout file.
Next, configure routing: (optional)
config.js
file:
export default {
plugins: [
['umi-plugin-react', {
dva: true, // 开启dva功能
antd: true // 开启Ant Design功能
}]
],
routes: [{
path: '/',
component: '../layouts' //配置布局路由
}]
};
To access the page:
As you can see, the layout has been generated, but the style is ugly.
Subpage usage layout
The layout defined earlier is a global layout. So, how to use this global layout in subpages?
First, you need to replace the Content
content with
{this.props.children}
in the layout file
, which means introducing the passed content.
import React from 'react'
import { Layout } from 'antd';
const { Header, Footer, Sider, Content } = Layout;
class BasicLayout extends React.Component{
render(){
return (
<Layout>
<Sider>Sider</Sider>
<Layout>
<Header>Header</Header>
<Content>{this.props.children}</Content>
<Footer>Footer</Footer>
</Layout>
</Layout>
);
}
}
export default BasicLayout;
Next configure routing (note, configure it under layout routing):
Note: The following routing configuration indicates that you need to access the page through manual configuration instead of using umi's default routing method.
export default {
plugins: [
['umi-plugin-react', {
dva: true, // 开启dva功能
antd: true // 开启Ant Design功能
}]
],
routes: [{
path: '/',
component: '../layouts', //配置布局路由
routes: [ //在这里进行配置子页面
{
path: '/myTabs',
component: './myTabs'
}
]
}]
};
To perform an access test:
As you can see, the global layout has been applied in the MyTabs component. The same goes for other subpages.
Beautify the page
Next, do some beautification work on the page:
import React from 'react'
import { Layout } from 'antd';
const { Header, Footer, Sider, Content } = Layout;
class BasicLayout extends React.Component{
render(){
return (
<Layout>
<Sider width={256} style={
{ minHeight: '100vh', color: 'white' }}>
Sider
</Sider>
<Layout>
<Header style={
{ background: '#fff', textAlign: 'center', padding:
0 }}>Header</Header>
<Content style={
{ margin: '24px 16px 0' }}>
<div style={
{ padding: 24, background: '#fff', minHeight: 360
}}>
{this.props.children}
</div>
</Content>
<Footer style={
{ textAlign: 'center' }}>后台系统 ©2022 Created by 大唐霸业</Footer>
</Layout>
</Layout>
);
}
}
export default BasicLayout;
Effect:
Introduce navigation bar
Use
Menu
component as navigation bar:
https://ant.design/components/menu-cn/
import React from 'react'
import {Layout, Menu, Icon} from 'antd';
const {Header, Footer, Sider, Content} = Layout;
const SubMenu = Menu.SubMenu;
class BasicLayout extends React.Component {
constructor(props){
super(props);
this.state = {
collapsed: false,
}
}
render() {
return (
<Layout>
<Sider width={256} style={
{minHeight: '100vh', color: 'white'}}>
<div style={
{ height: '32px', background: 'rgba(255,255,255,.2)',
margin: '16px'}}/>
<Menu
defaultSelectedKeys={['2']}
defaultOpenKeys={['sub1']}
mode="inline"
theme="dark"
inlineCollapsed={this.state.collapsed}
>
<Menu.Item key="1">
<Icon type="pie-chart"/>
<span>Option 1</span>
</Menu.Item>
<Menu.Item key="2">
<Icon type="desktop"/>
<span>Option 2</span>
</Menu.Item>
<Menu.Item key="3">
<Icon type="inbox"/>
<span>Option 3</span>
</Menu.Item>
<SubMenu key="sub1" title={<span><Icon type="mail"/>
<span>Navigation One</span></span>}>
<Menu.Item key="5">Option 5</Menu.Item>
<Menu.Item key="6">Option 6</Menu.Item>
<Menu.Item key="7">Option 7</Menu.Item>
<Menu.Item key="8">Option 8</Menu.Item>
</SubMenu>
<SubMenu key="sub2" title={<span><Icon type="appstore"/>
<span>Navigation Two</span></span>}>
<Menu.Item key="9">Option 9</Menu.Item>
<Menu.Item key="10">Option 10</Menu.Item>
<SubMenu key="sub3" title="Submenu">
<Menu.Item key="11">Option 11</Menu.Item>
<Menu.Item key="12">Option 12</Menu.Item>
</SubMenu>
</SubMenu>
</Menu>
</Sider>
<Layout>
<Header style={
{background: '#fff', textAlign: 'center', padding:
0}}>Header</Header>
<Content style={
{margin: '24px 16px 0'}}>
<div style={
{padding: 24, background: '#fff', minHeight: 360}}>
{this.props.children}
</div>
</Content>
<Footer style={
{textAlign: 'center'}}>后台系统 ©2018 Created by 大唐霸业</Footer>
</Layout>
</Layout>
);
}
}
export default BasicLayout;
Effect:
Add links to navigation
Next, we add links to the navigation bar on the left, and click the corresponding link to display the corresponding page on the right.
Create the user directory in
the src directory
, and create the UserAdd.js and UserList.js files in the user directory to simulate the functions of adding new users and querying user lists.
UserAdd.js
:
import React from 'react'
class UserAdd extends React.Component{
render(){
return (
<div>新增用户</div>
);
}
}
export default UserAdd;
UserList.js
:
import React from 'react'
class UserList extends React.Component{
render(){
return (
<div>用户列表</div>
);
}
}
export default UserList;
Next, configure routing:
export default {
plugins: [
['umi-plugin-react', {
dva: true, // 开启dva功能
antd: true // 开启Ant Design功能
}]
],
routes: [{
path: '/',
component: '../layouts', //配置布局路由
routes: [
{
path: '/myTabs',
component: './myTabs'
},
{
path: '/user',
routes: [
{
path: '/user/list',
component: './user/UserList'
},
{
path: '/user/add',
component: './user/UserAdd'
}
]
}
]
}]
};
Add a link to the menu:
import React from 'react'
import {Layout, Menu, Icon} from 'antd';
import Link from 'umi/link';
const {Header, Footer, Sider, Content} = Layout;
const SubMenu = Menu.SubMenu;
class BasicLayout extends React.Component {
constructor(props){
super(props);
this.state = {
collapsed: false,
}
}
render() {
return (
<Layout>
<Sider width={256} style={
{minHeight: '100vh', color: 'white'}}>
<div style={
{ height: '32px', background: 'rgba(255,255,255,.2)',
margin: '16px'}}/>
<Menu
defaultSelectedKeys={['1']}
defaultOpenKeys={['sub1']}
mode="inline"
theme="dark"
inlineCollapsed={this.state.collapsed}
>
<SubMenu key="sub1" title={<span><Icon type="user"/><span>用户管
理</span></span>}>
<Menu.Item key="1">
<Link to="/user/list">用户列表</Link>
</Menu.Item>
<Menu.Item key="2">
<Link to="/user/add">新增用户</Link>
</Menu.Item>
</SubMenu>
</Menu>
</Sider>
<Layout>
<Header style={
{background: '#fff', textAlign: 'center', padding:
0}}>Header</Header>
<Content style={
{margin: '24px 16px 0'}}>
<div style={
{padding: 24, background: '#fff', minHeight: 360}}>
{this.props.children}
</div>
</Content>
<Footer style={
{textAlign: 'center'}}>后台系统 ©2018 Created by 大唐霸业</Footer>
</Layout>
</Layout>
);
}
}
export default BasicLayout;
Note: The link tag of umi is used here to appear a menu that records clicks.
test:
Four: Form
Basic usage
Refer to the official documentation for implementation:
https://ant.design/components/table-cn/
Transform the
UserList.js
page:
import React from 'react'
import {Table, Divider, Tag, Pagination } from 'antd';
const {Column} = Table;
const data = [{
key: '1',
name: '张三',
age: 32,
address: '上海市',
tags: ['程序员', '帅气'],
}, {
key: '2',
name: '李四',
age: 42,
address: '北京市',
tags: ['屌丝'],
}, {
key: '3',
name: '王五',
age: 32,
address: '杭州市',
tags: ['高富帅', '富二代'],
}];
class UserList extends React.Component {
render() {
return (
<div>
<Table dataSource={data} pagination=
{
{position:"bottom",total:500,pageSize:10, defaultCurrent:3}}>
<Column
title="姓名"
dataIndex="name"
key="name"
/>
<Column
title="年龄"
dataIndex="age"
key="age"
/>
<Column
title="地址"
dataIndex="address"
key="address"
/>
<Column
title="标签"
dataIndex="tags"
key="tags"
render={tags => (
<span>
{tags.map(tag => <Tag color="blue" key={tag}>{tag}
</Tag>)}
</span>
)}
/>
<Column
title="操作"
key="action"
render={(text, record) => (
<span>
<a href="javascript:;">编辑</a>
<Divider type="vertical"/>
<a href="javascript:;">删除</a>
</span>
)}
/>
</Table>
</div>
);
}
}
export default UserList;
Realization effect:
Separate data into models
Implementation of model
:
UserListData.js
import request from "../util/request";
export default {
namespace: 'userList',
state: {
list: []
},
effects: {
*initData(params, sagaEffects) {
const {call, put} = sagaEffects;
const url = "/ds/user/list";
let data = yield call(request, url);
yield put({
type : "queryList",
data : data
});
}
},
reducers: {
queryList(state, result) {
let data = [...result.data];
return { //更新状态值
list: data
}
}
}
}
Modify
the logic in
UserList.js :
import React from 'react';
import { connect } from 'dva';
import {Table, Divider, Tag, Pagination } from 'antd';
const {Column} = Table;
const namespace = 'userList';
@connect((state)=>{
return {
data : state[namespace].list
}
}, (dispatch) => {
return {
initData : () => {
dispatch({
type: namespace + "/initData"
});
}
}
})
class UserList extends React.Component {
componentDidMount(){
this.props.initData();
}
render() {
return (
<div>
<Table dataSource={this.props.data} pagination=
{
{position:"bottom",total:500,pageSize:10, defaultCurrent:3}}>
<Column
title="姓名"
dataIndex="name"
key="name"
/>
<Column
title="年龄"
dataIndex="age"
key="age"
/>
<Column
title="地址"
dataIndex="address"
key="address"
/>
<Column
title="标签"
dataIndex="tags"
key="tags"
render={tags => (
<span>
{ tags.map(tag => <Tag color="blue" key={tag}>{tag}
</Tag>)}
</span>
)}
/>
<Column
title="操作"
key="action"
render={(text, record) => (
<span>
<a href="javascript:;">编辑</a>
<Divider type="vertical"/>
<a href="javascript:;">删除</a>
</span>
)}
/>
</Table>
</div>
);
}
}
export default UserList;
Mock
data:
MockListData.js
export default {
'get /ds/list': function (req, res) {
res.json({
data: [1, 2, 3, 4],
maxNum: 4
});
},
'get /ds/user/list': function (req, res) {
res.json([{
key: '1',
name: '张三1',
age: 32,
address: '上海市',
tags: ['程序员', '帅气'],
}, {
key: '2',
name: '李四',
age: 42,
address: '北京市',
tags: ['屌丝'],
}, {
key: '3',
name: '王五',
age: 32,
address: '杭州市',
tags: ['高富帅', '富二代'],
}]);
}
}
Test Results: