## 新建列表页面 1. 我们先做一个最简单的列表页面 2. 列表页面完整代码如下: ~~~ import React, { PureComponent } from 'react'; import { Button, Col, Form, Input, Row } from 'antd'; import Grid from '../../../components/Sword/Grid'; import Panel from '../../../components/Panel'; const FormItem = Form.Item; @Form.create() class Demo extends PureComponent { // ============ 查询表单 =============== renderSearchForm = onReset => { const { form } = this.props; const { getFieldDecorator } = form; return ( <Row gutter={{ md: 8, lg: 24, xl: 48 }}> <Col md={6} sm={24}> <FormItem label="标题"> {getFieldDecorator('title')(<Input placeholder="请输入标题" />)} </FormItem> </Col> <Col> <div style={{ float: 'right' }}> <Button type="primary" htmlType="submit"> 查询 </Button> <Button style={{ marginLeft: 8 }} onClick={onReset}> 重置 </Button> </div> </Col> </Row> ); }; render() { const code = 'demo'; const response = { code: 200, data: { total: 3, size: 10, current: 1, searchCount: true, pages: 1, records: [ { id: '1', title: '测试标题1', content: '测试内容1', date: '2018-05-08 12:00:00', }, { id: '2', title: '测试标题2', content: '测试内容2', date: '2018-06-08 12:00:00', }, { id: '3', title: '测试标题3', content: '测试内容3', date: '2018-07-08 12:00:00', }, ], }, message: 'success', success: true, }; const data = { list: response.data.records, pagination: { total: response.data.total, current: response.data.current, pageSize: response.data.size, }, }; const { form, loading } = this.props; const columns = [ { title: '标题', dataIndex: 'title', }, { title: '内容', dataIndex: 'content', }, { title: '时间', dataIndex: 'date', }, ]; return ( <Panel> <Grid code={code} form={form} onSearch={this.handleSearch} renderSearchForm={this.renderSearchForm} loading={loading} data={data} columns={columns} /> </Panel> ); } } export default Demo; ~~~ 3. 我们来详细分析每一个代码块的作用及目的 4. 首先第一层import,是为了将所用到的组件、封装都引入进来进行页面的渲染使用 ~~~ import React, { PureComponent } from 'react'; import { Button, Col, Form, Input, Row } from 'antd'; import Grid from '../../../components/Sword/Grid'; import Panel from '../../../components/Panel'; ~~~ 5. 接下来是定义整个类,进行完整的导出,用作路由发现并渲染页面。FormItem定义后可直接变为可引用的标签 `<FormItem>` 简化了代码 ~~~ const FormItem = Form.Item; @Form.create() class Demo extends PureComponent { } ~~~ 6. renderSearchForm方法封装了搜索模块,只需定义搜索模块的表单元素并传入到下面封装的Grid组件,即可自动生成查询重置等功能,更复杂的功能,都可以通过这个函数进行拓展 ~~~ renderSearchForm = onReset => { const { form } = this.props; const { getFieldDecorator } = form; return ( <Row gutter={{ md: 8, lg: 24, xl: 48 }}> <Col md={6} sm={24}> <FormItem label="标题"> {getFieldDecorator('title')(<Input placeholder="请输入标题" />)} </FormItem> </Col> <Col> <div style={{ float: 'right' }}> <Button type="primary" htmlType="submit"> 查询 </Button> <Button style={{ marginLeft: 8 }} onClick={onReset}> 重置 </Button> </div> </Col> </Row> ); }; ~~~ 7. render函数返回的就是Demo组件最终渲染的元素 ~~~ render() { } ~~~ 8. `const code = 'demo';`定义了此模块的菜单code是demo,传入Grid组件后,便会根据设定好的code至去查找所拥有的按钮集最后呈现在页面上。若新建了另一个模块demo1,则此时的code也改为demo1,与菜单code保持一致 9. 再往下的response和data,则定义了Grid组件所需呈现的数据源。response模拟了接口返回的数据,而data则是对返回数据进行了二次加工,从而变为组件可识别的数据格式 ~~~ const response = { code: 200, data: { total: 3, size: 10, current: 1, searchCount: true, pages: 1, records: [ { id: '1', title: '测试标题1', content: '测试内容1', date: '2018-05-08 12:00:00', }, { id: '2', title: '测试标题2', content: '测试内容2', date: '2018-06-08 12:00:00', }, { id: '3', title: '测试标题3', content: '测试内容3', date: '2018-07-08 12:00:00', }, ], }, message: 'success', success: true, }; const data = { list: response.data.records, pagination: { total: response.data.total, current: response.data.current, pageSize: response.data.size, }, }; ~~~ 10. 最后一段代码则是定义了Grid所需显示的字段,以及所有数据的汇总,都设定在了Grid组件里 ~~~ const { form, loading } = this.props; const columns = [ { title: '标题', dataIndex: 'title', }, { title: '内容', dataIndex: 'content', }, { title: '时间', dataIndex: 'date', }, ]; return ( <Panel> <Grid code={code} form={form} onSearch={this.handleSearch} renderSearchForm={this.renderSearchForm} loading={loading} data={data} columns={columns} /> </Panel> ); ~~~ 11. 好了,源码分析完了,我们打开系统查看下对应的效果,发现一个列表也已然生成,数据内容与我们设置的一样 ![](https://box.kancloud.cn/16cae93e53dbbaca81e3adfd0d56c3fa_3354x1362.png) 12. 如果页面都把数据写成固定的,那么这个模块基本没有价值,Grid显示的数据必须是动态的对接接口的,所以我们下面来学习下如何将数据对接接口,让他活起来。 <br> ## 对接列表接口 1. 在demo.js中加入`getFakeList`,定义数据返回(注意json格式要严格按照截图中所来),否则grid组件加载会出问题 ![](https://box.kancloud.cn/b73828bb02e807df7b4597242afa2171_1998x1622.png) 2. 打开postman调用mock接口查看返回成功 ![](https://box.kancloud.cn/bb7c2508785f2f94867fd244e9a7aabc_1096x1720.png) 3. 我们到services文件夹下定义这个新增的接口 ![](https://box.kancloud.cn/29ddbbda330ac8cb619e2ef014ff3779_1968x550.png) 4. 优化列表页代码,加入接口动态对接 ~~~ import React, { PureComponent } from 'react'; import { Button, Col, Form, Input, Row } from 'antd'; import Grid from '../../../components/Sword/Grid'; import Panel from '../../../components/Panel'; import { list } from '../../../services/demo'; const FormItem = Form.Item; @Form.create() class Demo extends PureComponent { state = { data: {}, }; componentWillMount() { list().then(response => { this.setState({ data: { list: response.data.records, pagination: { total: response.data.total, current: response.data.current, pageSize: response.data.size, }, }, }); }); } // ============ 查询表单 =============== renderSearchForm = onReset => { const { form } = this.props; const { getFieldDecorator } = form; return ( <Row gutter={{ md: 8, lg: 24, xl: 48 }}> <Col md={6} sm={24}> <FormItem label="模块名"> {getFieldDecorator('title')(<Input placeholder="请输入模块名" />)} </FormItem> </Col> <Col> <div style={{ float: 'right' }}> <Button type="primary" htmlType="submit"> 查询 </Button> <Button style={{ marginLeft: 8 }} onClick={onReset}> 重置 </Button> </div> </Col> </Row> ); }; render() { const code = 'demo'; const { data } = this.state; const { form, loading } = this.props; const columns = [ { title: '标题', dataIndex: 'title', }, { title: '内容', dataIndex: 'content', }, { title: '时间', dataIndex: 'date', }, ]; return ( <Panel> <Grid code={code} form={form} onSearch={this.handleSearch} renderSearchForm={this.renderSearchForm} loading={loading} data={data} columns={columns} /> </Panel> ); } } export default Demo; ~~~ 5. 可以看出,我们将data放入了state,并在组件将要加载的时候调用api接口,返回的时候将数据重新写入到state中,从而刷新渲染,显示出了数据。 6. 打开页面刷新,发现数据加载成功