我们已经实现了文章列表的分页查询,接下来我们需要实现文章列表的条件查询 .
1. 条件查询布局
如果之前学过不凡学院的乐居商城后台管理系统,那么这一块的布局思路应该非常熟悉:
<PageContainer className={styles.main}><Card className={styles.searchBar}><FormlabelCol={{span: 4,}}wrapperCol={{span: 20,}}layout="inline"><Row gutter={[20,30]} style={{width:'100%'}}><Col span={6}><Form.Item label="标题" name="title"><Input /></Form.Item></Col><Col span={6}><Form.Item label="作者" name="author"><Input /></Form.Item></Col><Col span={6} offset={18}><Form.Item><Button type="ghost">重置</Button><Button type="primary" htmlType="submit" style={{marginLeft: '20px'}}>查询</Button></Form.Item></Col></Row></Form></Card>...</PageContainer>// ==> ./index.less.main{.searchBar{background-color: #fff;margin-bottom: 30px;}}
2. 实现查询功能
// React是导出的默认组件,所以不需要加{},而useEffect是单独导出的组件,需要加{}import React, { useEffect, useState } from 'react';import { PageContainer } from '@ant-design/pro-layout';// 引入connectimport { connect } from 'umi';import type { Dispatch } from 'umi';import type { MStateType } from './model';import { Table, Card, Form, Input, Button, Row, Col } from 'antd';import { pickBy } from 'lodash';import type { ConnectState } from '@/models/connect.d';// 声明命名空间const namespace = 'article';// 声明props类型type PropsType = {articleList: []; // ??dispatch: Dispatch;totalCount: number;loading: boolean;};const ArticleList: React.FC<PropsType> = (props) => {// 解构需要用的内容const { articleList, totalCount, dispatch, loading } = props;// 某个数据是动态的 我们就得使用"响应式"对象得形式声明,也就是说哪写值变化了,需要更新页面,就需要声明成state// 在函数式组件中,因为无法使用this,所以提出来hook形式解决// useState 返回了一个数组,第一个参数是变量(响应式对象)名称,第二个是函数名,可以通过第二个函数更新这个变量const [pageStart, setPageStart] = useState<number>(1);const [pageSize, setPageSize] = useState<number>(10);// 定义查询条件const [params, setParams] = useState({});// 发送请求 尝试发送请求// 声明周期函数// componentDidMount(){// }// useEffect是多个生命周期函数的集合,考虑在这里进行数据初始化/请求// useEffect 第一个参数是函数类型,用于触发事件, 第二个参数是依赖于哪写数据的变化才触发// 如果只希望在第一次进入的时候触发一次,那么第二个参数为[]数组// useEffect componetDidMount componentDidUpdate componentWillUnmountuseEffect(() => {dispatch({type: `${namespace}/findArticleList`,payload: {start: pageStart,limit: pageSize,params,},});}, [pageStart, pageSize, params]);// 用于控制数据列const columns = [{title: 'id',dataIndex: 'id',key: 'id',},{title: '标题',dataIndex: 'title',key: 'title',},{title: '作者',dataIndex: 'author',key: 'author',},{title: '概要描述',dataIndex: 'summary',key: 'summary',},{title: '创建时间',dataIndex: 'createTime',key: 'createTime',},];// 比葫芦画瓢 找到form组件 定义了form的refconst [form] = Form.useForm();const onChange = (pageNumber: number, pSize?: number) => {// 页面变化的时候触发 需要更改分页变化// console.log('Page: ', pageNumber,pSize);setPageStart(pageNumber);setPageSize(pSize!);};// 查询的时候触发 如果需要刷新页面,本质需求是改变params对象 触发effectconst onSearch = (value: { title?: string; author?: string }) => {// {author: 'zs', title: undefined} => {author: 'zs'}let useParams = { ...value };useParams = pickBy(useParams, (item) => item);// console.log(useParams);setParams({...useParams,});};const resetSearch = () => {form.resetFields();setParams({});};return (<PageContainer><Card title="条件查询" style={{ width: '100%', marginBottom: '30px' }}><Form labelCol={{ span: 6 }} wrapperCol={{ span: 18 }} onFinish={onSearch} form={form}><Row gutter={32}><Col span={6}><Form.Item label="标题" name="title"><Input /></Form.Item></Col><Col span={6}><Form.Item label="作者" name="author"><Input /></Form.Item></Col></Row><Row gutter={32}><Col span={6} offset={18} style={{ textAlign: 'right' }}><Button onClick={resetSearch}>重置</Button>{/* htmlType="submit" 把button变成表单默认提交按钮 用于触发onFinish */}<Button type="primary" style={{ marginLeft: 30 }} htmlType="submit">查询</Button></Col></Row></Form></Card><Tableloading={loading}pagination={{showQuickJumper: true,showSizeChanger: true,current: pageStart,pageSize,total: totalCount,onChange,}}rowKey="id"dataSource={articleList}columns={columns}/>;</PageContainer>);};// 绑定model和组件 把state映射到props// 自定义的state不符合,但是可以合并connect.d.ts中的connectStatetype StateType = {[namespace]: MStateType;} & ConnectState;const mapStateToProps = (state: StateType) => ({articleList: state[namespace].articleList,totalCount: state[namespace].totalCount,loading: state.loading.effects['article/findArticleList'] as boolean,});export default connect(mapStateToProps)(ArticleList);
总结: 分页查询和条件查询我们已经基本实现, 跟vue相比, useEffect 确实很方便 . 接下来我们实现文章的新增功能.
