ant-design 简单学习,记录一下。
ant-design-pro官网v4 附带开发手册 效果预览
umi脚手架
因为umi是阿里工具,所以使用tyarn安装。
# 安装$ yarn global add umi# 更新umiyarn global upgrade umi
项目初始化
# 新建应用yarn create umi project_name选择 antd 、 dva 、js、npm
新建页面
export default () => {return <div>hello world</div>;}
外部可以引用
import React from 'react';class ShoppingList extends React.Component {constructor(props) {super(props);this.state = {value: null,};}componentDidMount() {}componentWillUnmount() {}componentDidUpdate() {}render() {const picture = {src: 'https://cdn.nlark.com/yuque/0/2018/jpeg/84141/1536207007004-59352a41-4ad8-409b-a416-a4f324eb6d0b.jpeg',};return (<div className="shopping-list"><h1>Shopping List for {this.props.name}</h1><ul><li>Instagram</li><li>WhatsApp</li><li>Oculus</li></ul></div>);}}export default ShoppingList;
路由
routes: [{path: '/user',component: '../layouts/UserLayout',routes: [{name: 'login',path: '/user/login',component: './user/login',},{name: 'UserDashboard',icon: 'smile',path: '/user-dashboard',component: './user-dashboard',},],},{path: '/',component: '../layouts/SecurityLayout',routes: [{path: '/',component: '../layouts/BasicLayout',authority: ['admin', 'user'],routes: [{path: '/',redirect: '/welcome',},{path: '/welcome',name: 'welcome',icon: 'smile',component: './Welcome',},{name: '监控页',icon: 'smile',path: '/dashboardmonitor1',component: './DashboardMonitor',},{component: './404',},],},{component: './404',},],},{component: './404',},],
布局
import { Layout } from 'antd';const { Header, Footer, Sider, Content } = Layout;ReactDOM.render(<div><Layout><Header>Header</Header><Content>Content</Content><Footer>Footer</Footer></Layout><Layout><Sider>Sider</Sider><Layout><Header>Header</Header><Content>Content</Content><Footer>Footer</Footer></Layout></Layout></div>,mountNode,);
栅格
import { Row, Col } from 'antd';ReactDOM.render(<div><Row><Col span={12}>col-12</Col><Col span={12}>col-12</Col></Row><Row><Col span={8}>col-8</Col><Col span={8}>col-8</Col><Col span={8}>col-8</Col></Row></div>,mountNode,);
示例
效果:

结构:

index.jsx
页面元素
import React from 'react';import { connect } from 'dva';import { Table, Modal, Button, Form, Input } from 'antd';import SampleChart from '../../components/SampleChart';const FormItem = Form.Item;class List extends React.Component {state = {visible: false,statisticVisible: false,id: null,};columns = [{title: '名称',dataIndex: 'name',},{title: '描述',dataIndex: 'desc',},{title: '链接',dataIndex: 'url',render: value => <a href={value}>{value}</a>,},{title: '',dataIndex: 'statistic',render: (_, { id }) => {return (<Button onClick={() => { this.showStatistic(id); }}>图表</Button>);},},];showModel = () => {this.setState({ visible: true })};handleCancel = () => {this.setState({visible: false,});};handleStatisticCancel = () => {this.setState({statisticVisible: false,});};showStatistic = (id) => {this.props.dispatch({type: 'cards/getStatistic',payload: id,});this.setState({ id, statisticVisible: true });};handleOk = () => {const { dispatch, form: { validateFields } } = this.props;validateFields((err, values) => {if (!err) {dispatch({type: 'cards/addOne',payload: values,});// 重置 `visible` 属性为 false 以关闭对话框this.setState({ visible: false });}});};componentDidMount() {this.props.dispatch({type: 'cards/queryList',});}render() {const { visible, statisticVisible, id } = this.state;const { cardsList, cardsLoading, form: { getFieldDecorator }, statistic } = this.props;return (<div><Table columns={this.columns} dataSource={cardsList} loading={cardsLoading} rowKey="id"/><Button onClick={this.showModel}>新建</Button><Modal title="新建记录"visible={visible}onOk={this.handleOk}onCancel={this.handleCancel}><Form><FormItem label="名称">{getFieldDecorator('name', {rules: [{ required: true }],})(<Input/>)}</FormItem><FormItem label="描述">{getFieldDecorator('desc')(<Input/>)}</FormItem><FormItem label="链接">{getFieldDecorator('url', {rules: [{ type: 'url' }],})(<Input/>)}</FormItem></Form></Modal><Modal visible={statisticVisible} footer={null} onCancel={this.handleStatisticCancel}><SampleChart data={statistic[id]} /></Modal></div>);}}function mapStateToProps(state) {return {cardsList: state.cards.cardsList,cardsLoading: state.loading.effects['cards/queryList'],statistic: state.cards.statistic,};}export default connect(mapStateToProps)(Form.create()(List));
model.js
页面所有方法
import * as service from './service';export default {namespace: 'cards',state: {cardsList: [],statistic: {},},effects: {* queryList({ payload }, { call, put }) {const rsp = yield call(service.queryList, payload);yield put({type: 'initList',payload: { cardsList: rsp.result }});},*deleteOne({ payload }, { call, put }) {const rsp = yield call(service.deleteOne, payload);return rsp;},*addOne({ payload }, { call, put }) {const rsp = yield call(service.addOne, payload);yield put({ type: 'queryList' });return rsp;},*getStatistic({ payload }, { call, put }) {const rsp = yield call(service.getStatistic, payload);yield put({type: 'saveStatistic',payload: {id: payload,data: rsp.result,},});return rsp;},},reducers: {initList(state, { payload: { cardsList } }) {return {...state,cardsList};},saveStatistic(state, { payload: { id, data } }) {return {...state,statistic: {...state.statistic,[id]: data,},}},}};
service.js
所有异步请求
import request from '@/utils/request';export function queryList() {return request('/api/cards');}export function deleteOne(id) {return request(`/api/cards/${id}`, {method: 'DELETE'});}export function addOne(data) {return request('/api/cards/add', {headers: {'content-type': 'application/json',},method: 'POST',body: JSON.stringify(data),});}export function getStatistic(id) {return request(`/api/cards/${id}/statistic`);}
_mock.js
模拟数据
let data = [{id: 1,name: 'umi',desc: '极快的类 Next.js 的 React 应用框架。',url: 'https://umijs.org'},{id: 2,name: 'antd',desc: '一个服务于企业级产品的设计体系。',url: 'https://ant.design/index-cn'},{id: 3,name: 'antd-pro',desc: '一个服务于企业级产品的设计体系。',url: 'https://ant.design/index-cn'}];export default {'get /api/cards': function (req, res, next) {setTimeout(() => {res.json({result: data,})}, 250)},'delete /api/cards/:id': function (req, res, next) {data = data.filter(v => v.id !== parseInt(req.params.id));console.log(req.params.id);console.log(data);setTimeout(() => {res.json({success: true,})}, 250)},'post /api/cards/add': function (req, res, next) {data = [...data, {...req.body,id: data[data.length - 1].id + 1,}];res.json({success: true,});},'get /api/cards/:id/statistic': function (req, res, next) {res.json({result: [{ genre: 'Sports', sold: 275 },{ genre: 'Strategy', sold: 1150 },{ genre: 'Action', sold: 120 },{ genre: 'Shooter', sold: 350 },{ genre: 'Other', sold: 150 },]});},}
附带一个 SampleChart
import React from 'react';import G2 from '@antv/g2';class SampleChart extends React.Component {constructor(props) {super(props);this.containerRef = React.createRef();}componentDidMount() {this.chart = new G2.Chart({container: this.containerRef.current,width: 450,height: 300});this.refreshChart();}componentDidUpdate(prevProps) {if (prevProps.data !== this.props.data) {this.refreshChart();}}componentWillUnmount() {if (this.chart) {this.chart.destroy();}}refreshChart = () => {this.chart.source(this.props.data);this.chart.interval().position('genre*sold').color('genre');this.chart.render();};render() {return (<div ref={this.containerRef} />);}}export default SampleChart;
表单操作
数据绑定:
const [noteForm] = Form.useForm();<Form{...layout}name="basic"initialValues={{}}onFinish={updatePushUrl}form={noteForm}// onFinishFailed={onFinishFailed}><Form.Itemlabel="提醒地址"name="noteUrl"><Input/></Form.Item><Form.Item {...tailLayout}><Button type="primary" htmlType="submit">提交</Button></Form.Item></Form>
赋值
noteForm.setFieldsValue({"noteUrl": res.data});
提交
const updatePushUrl = (values: PushChange) => {service.updatePushUrl(values);}
