当前位置: 首页 > 科技观察

列表页常见的Hook包,你知道几个?_0

时间:2023-03-15 15:16:50 科技观察

列表页常用元素对于一些后台管理系统来说,一个典型的列表页包括三个部分:filterformitems、Table表格和Pagination分页。对于使用Antd的系统,ahooks主要封装在useAntdTable和usePagination两个hooks上。usePaginationusePagination是基于useRequest实现的,封装了常用的分页逻辑。首先通过useRequest处理请求,服务协议返回的数据结构为{total:number,list:Item[]}。useRequest的defaultParams参数的第一个参数是{current:number,pageSize:number}。并根据请求的参数和返回的合计值,得到总页数。还有一个refreshDeps变化,会把current重置为第一页“changeCurrent(1)”,重新发起请求。一般来说,你可以把分页依赖条件放在这里。constusePagination=(service:Service,options:PaginationOptions={},)=>{const{defaultPageSize=10,...rest}=复制代码选项;//service返回的数据结构为{total:number,list:Item[]}constresult=useRequest(service,{//service第一个参数为{current:number,pageSize:number}defaultParams:[{current:1,pageSize:defaultPageSize}],//refreshDeps变化,会重置当前到第一页,重新发起请求,一般可以把分页依赖条件放在这里refreshDepsAction:()=>{//eslint-禁用下一行@typescript-eslint/no-use-before-definechangeCurrent(1);},...rest,});//获取相关请求参数const{current=1,pageSize=defaultPageSize}=result.params[0]||{};//获取请求结果,total表示数据总数consttotal=result.data?.total||0;//获取总页数consttotalPage=useMemo(()=>Math.ceil(total/pageSize),[pageSize,total]);}关注onChange方法:入参为当前页码和当前页面大小最大数从total计算总页数。获取所有参数并执行请求逻辑。当修改当前页或者每个当前页的最大页数时,直接调用onChange方法即可。//c代表当前页面//p代表页面大小constonChange=(c:number,p:number)=>{lettoCurrent=c<=0?1:c;consttoPageSize=p<=0?1:p;//根据total计算总页数consttempTotalPage=Math.ceil(total/toPageSize);//如果此时总页数小于当前页,则当前页需要分配总页数if(toCurrent>tempTotalPage){toCurrent=Math.max(1,tempTotalPage);}const[oldPaginationParams={},...restParams]=result.params||[];//重新执行请求result.run(//注意参数变化,主要是当前页数和每页总页数变化{...oldPaginationParams,current:toCurrent,pageSize:toPageSize,},...休息参数,);};constchangeCurrent=(c:number)=>{onChange(c,pageSize);};constchangePageSize=(p:number)=>{onChange(current,p);};最后返回请求的结果和分页字段,包括所有的分页信息。还有用于操作分页的函数。return{...result,//会额外返回分页字段,包括所有分页信息,以及操作分页的函数。分页:{当前,pageSize,总计,totalPage,onChange:useMemoizedFn(onChange),changeCurrent:useMemoizedFn(changeCurrent),changePageSize:useMemoizedFn(changePageSize),},}作为PaginationResult;一致,但内部封装了与寻呼请求相关的逻辑。返回结果多返回一个分页参数,包含所有分页信息和操作分页的函数。缺点是API请求参数有限制。比如输入参数结构必须是{current:number,pageSize:number},返回结果是{total:number,list:Item[]}。useAntdTableuseAntdTable是基于useRequest实现的,封装了常用的AntDesignForm和AntDesignTable联动逻辑,同时支持antdv3和v4。首先调用usePagination来处理分页逻辑。constuseAntdTable=(service:Service,options:AntdTableOptions={},)=>{const{//表单实例表单,//默认表单optiondefaultType='simple',//默认参数,第一项为分页数据,第二项为表单数据。[pagination,formData]defaultParams,manual=false,//refreshDeps发生变化,会将当前重置为第一页,并重新发起请求。refreshDeps=[],ready=true,...rest}=选项;//处理分页逻辑//Pagination也是对useRequest的重新封装constresult=usePagination(service,{manual:true,...rest,});//...}然后处理列表页Form表单过滤的逻辑,这里支持Antdv3和Antdv4版本。//判断是否是Antd第四版constisAntdV4=!!form?.getInternalHooks;获取当前表单值,form.getFieldsValue或form.getFieldInstance://从值中获取当前值constgetActiveFieldValues=()=>{if(!form){return{};}//antd4if(isAntdV4){returnform.getFieldsValue(null,()=>true);}//antd3constallFieldsValue=form.getFieldsValue();constactiveFieldsValue={};Object.keys(allFieldsValue).forEach((key:string)=>{if(form.getFieldInstance?form.getFieldInstance(key):true){activeFieldsValue[key]=allFieldsValue[key];}});返回activeFieldsValue;};验证表单逻辑form.validateFields://验证逻辑constvalidateFields=():Promise>=>{if(!form){returnPromise.resolve({});}constactiveFieldsValue=getActiveFieldValues();constfields=Object.keys(activeFieldsValue);//antd4//validateFields直接调用if(isAntdV4){return(form.validateFieldsasAntd4ValidateFields)(fields);}//antd3returnnewPromise((resolve,reject)=>{form.validateFields(fields,(errors,values)=>{if(errors){reject(errors);}else{resolve(values);}});});};重置表单form.setFieldsValue://重置表单constrestoreForm=()=>{if(!form){return;}//antdv4if(isAntdV4){returnform.setFieldsValue(allFormDataRef.current);}//antdv3constactiveFieldsValue={};Object.keys(allFormDataRef.current).forEach((key)=>{if(form.getFieldInstance?form.getFieldInstance(key):true){activeFieldsValue[key]=allFormDataRef.current[key];}});form.setFieldsValue(activeFieldsValue);};修改表单类型,支持'simple'和'advanced'初始化表单数据,可以填写全量的simple和advance表单数据,开发者可以根据当前激活的类型设置表单数据。当类型被修改时,表单数据将被重置。constchangeType=()=>{//获取当前表单值constactiveFieldsValue=getActiveFieldValues();//修改表单值allFormDataRef.current={...allFormDataRef.current,...activeFieldsValue,};//设置表单类型setType((t)=>(t==='simple'?'advance':'simple'));};//修改类型,然后重置表单表单数据useUpdateEffect(()=>{if(!ready){return;}restoreForm();},[type]);_submit方法:表单验证后,根据当前表单数据、分页等过滤条件查找表数据。const_submit=(initPagination?:TParams[0])=>{setTimeout(()=>{//先验证validateFields().then((values={})=>{//分页逻辑constpagination=initPagination||{pageSize:options.defaultPageSize||10,...(params?.[0]||{}),current:1,};//如果没有表单,则直接按照分页逻辑if(!form){//@ts-ignorerun(pagination);return;}//获取所有当前表单的数据参数//记录所有表单数据allFormDataRef.current={...allFormDataRef.current,...values,};//@ts-ignorerun(pagination,values,{allFormData:allFormDataRef.current,type,});}).catch((err)=>err);});};当触发onChange方法时,也会请求://Table组件的onChange事件constonTableChange=(pagination:any,filters:any,sorter:any)=>{const[oldPaginationParams,...restParams]=par艾迈斯半导体||[];run(//@ts-ignore{...oldPaginationParams,current:pagination.current,pageSize:pagination.pageSize,filters,sorter,},...restParams,);};初始化的时候会根据当前是否有缓存的数据来执行请求逻辑,否则通过manual和ready判断是否需要重新设置表单,然后执行请求逻辑。//初始化逻辑//inituseEffect(()=>{//如果有缓存,使用缓存的参数。忽略手动和准备。//params.length>0,表示有缓存if(params.length>0){//使用缓存数据allFormDataRef.current=cacheFormTableData?.allFormData||{};//重置表单后执行请求restoreForm();//@ts-ignorerun(...params);return;}//非手动且准备就绪,执行_submitif(!manual&&ready){allFormDataRef.current=defaultParams?.[1]||{};restoreForm();_submit(defaultParams?.[0]);}},[]);最后将请求返回的数据通过dataSource、分页、加载等方式传回Table组件,实现Table数据和状态的展示。并将Form表单上的一些操作方法暴露给开发者。return{...result,//Table组件需要的数据可以直接传给Table组件。tableProps:{dataSource:result.data?.list||defaultDataSourceRef.current,loading:result.loading,onChange:useMemoizedFn(onTableChange),pagination:{current:result.pagination.current,pageSize:result.pagination.pageSize,total:result.pagination.total,},},搜索:{//提交表单submit:useMemoizedFn(submit),//当前表单类型,简单|advancetype,//切换表单类型changeType:useMemoizedFn(changeType),//重置当前表单reset:useMemoizedFn(reset),},}asAntdTableResult;

最新推荐
猜你喜欢